Đây là giải pháp chung mà tôi nghĩ sẽ thực hiện công việc cho bạn. Nó không được tối ưu hóa cho hiệu suất, cũng không được kiểm tra đặc biệt tốt.
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();
}
}
Sửa 1: tổng quan cấp cao của thuật toán
- Tìm tất cả yếu tố trẻ hoặc bằng,
- Đối với tất cả yếu tố trẻ hoặc bằng, xem nếu bất kỳ có một B cao hơn
- Nếu (2) trả lại
- Tìm tất cả các thành phần cũ hơn
- Nếu bất kỳ phần tử nào có điểm thấp hơn, hãy xóa
- Sắp xếp danh sách theo thứ tự tăng dần (bởi A)
Chỉnh sửa 2: Tốc độ có thể dễ dàng được tăng thêm a) một khi bạn tìm thấy các yếu tố trẻ, bạn có thể tiếp tục từ thời điểm đó khi tìm kiếm các yếu tố trai thay vì lặp lại tất cả lần nữa, và b) thay vì sắp xếp nó bằng cách sử dụng phương pháp sắp xếp danh sách, bạn có thể sử dụng InsertAt (0 hoặc chỉ số của người cao tuổi đầu tiên)
Ý tưởng đầu tiên là giữ cấu trúc dữ liệu được sắp xếp (một phần có thể) cho phần tử đầu tiên của cặp vợ chồng và phần tử song song cho phần tử thứ hai sau khi bạn chèn phần tử vào cấu trúc dữ liệu đầu tiên sẽ có thể chèn phần tử thứ hai vào vị trí tương ứng (vị trí tương tự cho một đống, cùng một đường dẫn cho một cây) nếu không nó có nghĩa là bạn phải loại bỏ phần tử. – Teudimundo
Bạn yêu cầu loại hiệu suất nào? Tôi nhận thấy rằng phương pháp chèn vào tiệm cận sẽ là O (n) vì nó có thể phải xóa tất cả dữ liệu khác trong bộ sưu tập. Có ổn không nếu chèn luôn luôn là tuyến tính, O (n)? Nếu vậy, tôi chỉ sử dụng một danh sách liên kết. Nếu không, chúng tôi có thể cần một số loại cấu trúc cây, và chúng tôi sẽ viết nhiều mã hơn! – PaulF