以下是我认为能为您完成这项工作的通用解决方案。它没有针对性能进行优化,也没有特别好的测试。
public class AgePair<T, Y>
where T : IComparable<T>
where Y : IComparable<Y>
{
public T A { get; set; }
public Y B { get; set; }
}
public class AgeRecordList<T, Y> : IEnumerable<AgePair<T,Y>>
where T : IComparable<T>
where Y : IComparable<Y>
{
private List<AgePair<T, Y>> m_List = new List<AgePair<T, Y>>();
public void Add(T a, Y b)
{
AgePair<T, Y> newPair = new AgePair<T, Y> { A = a, B = b };
// Get all elements that are younger
var younger = GetYounger(newPair.A);
// Find any of the younger with a higher score
// If found, return without inserting the element
foreach (var v in younger)
{
if (v.B.CompareTo(newPair.B) >= 0)
{
return;
}
}
// Cache elements to delete
List<AgePair<T, Y>> toDelete = new List<AgePair<T, Y>>();
// Find all the elder elements
var elder = GetElder(newPair.A);
// Find all elder elements with a lower B
foreach (var v in elder)
{
if (v.B.CompareTo(newPair.B) <= 0)
{
// Mark for delete
toDelete.Add(v);
}
}
// Delete those elements found above
foreach (var v in toDelete)
{
m_List.Remove(v);
}
// Add the new element
m_List.Add(newPair);
// Sort the list (ascending by A)
m_List.Sort(CompareA);
}
private List<AgePair<T, Y>> GetElder(T t)
{
List<AgePair<T, Y>> result = new List<AgePair<T, Y>>();
foreach (var current in m_List)
{
if (t.CompareTo(current.A) <= 0)
{
result.Add(current);
}
}
return result;
}
private List<AgePair<T, Y>> GetYounger(T t)
{
List<AgePair<T, Y>> result = new List<AgePair<T, Y>>();
foreach (var current in m_List)
{
if (t.CompareTo(current.A) > 0)
{
result.Add(current);
}
}
return result;
}
private static int CompareA(AgePair<T,Y> item1, AgePair<T,Y> item2)
{
return item1.A.CompareTo(item2.A);
}
public IEnumerator<AgePair<T, Y>> GetEnumerator()
{
return m_List.GetEnumerator();
}
}
编辑1:算法的高级概述
- 找到所有年轻或等于元素,
- 对于所有年轻的或相同的元件,看是否有一个以上B
- 如果(2)返回
- 查找所有老年人元素
- 如果任何老年人元素得分较低,请删除
- 排序列表按升序(按A)
编辑2:速度可以很容易地通过增加),一旦你找到了年轻的元素,你可以从该点寻找老人元素,而不是在继续b)不用使用List的排序方法对它排序,而是使用InsertAt(0或第一个长辈的索引)
我的第一个想法是保持排序的数据结构(可能是堆)为夫妇的第一个元素和一个并联一个第二元素,一旦你在第一数据结构中插入一个元素你应该能够将第二个元素插入相应的位置(堆的位置相同,树的路径相同),否则就意味着必须丢弃该元素。 – Teudimundo
你需要什么样的表现?我注意到渐近地插入方法将是O(n),因为它可能需要删除集合中的所有其他数据。如果插入总是线性的,O(n)是可以的吗?如果是这样,我只是使用链表。如果不是,我们可能需要某种树结构,我们会写更多的代码! – PaulF