Aquí hay una solución genérica que creo que hará el trabajo por usted. No está optimizado para el rendimiento, ni está particularmente bien probado.
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();
}
}
Edición 1: visión general de nivel alto del algoritmo
- Buscar Todos los elementos más jóvenes o iguales,
- Para todos los elementos más jóvenes o iguales, ver si alguno tienen un mayor B
- Si (2) return
- Buscar todos los elementos antiguos
- Si algún elemento anterior tiene una puntuación más baja, elimine
- ordenar la lista en orden ascendente (de A)
Edición 2: La velocidad se puede incrementar fácilmente por a) una vez que encontramos los elementos más jóvenes, puede continuar desde ese punto en la búsqueda de elementos mayores en lugar de iterando sobre todo otra vez, yb) en lugar de ordenarlo usando el método Sort de List, puede usar InsertAt (0 o índice de primer élder)
La primera idea que tuve es mantener una estructura de datos ordenados (un montón tal vez) para el primer elemento de la pareja y uno paralelo para el segundo elemento, una vez que se inserta un elemento de la primera estructura de datos que debería ser capaz de insertar el segundo elemento en la posición correspondiente (la misma posición para un montón, la misma ruta para un árbol), de lo contrario, significa que debe descartar el elemento. – Teudimundo
¿Qué tipo de rendimiento requiere? Observo que asintóticamente el método de inserción será O (n) ya que podría tener que eliminar todos los demás datos en la colección. ¿Está bien si la inserción es siempre lineal, O (n)? Si es así, solo usaría una lista vinculada. Si no, probablemente necesitaríamos algún tipo de estructura de árbol, ¡y estaríamos escribiendo mucho más código! – PaulF