Как вставить несколько объектов в отсортированный список C # по порядку, когда я получил CompareTo () - PullRequest
0 голосов
/ 01 апреля 2019

Моя домашняя работа: я получил общий список в C #, я сортировал его по List.Sort, когда реализовано CompareTo(). У меня есть другой список объектов той же структуры, и мне нужно вставить их в мой первый отсортированный список, не добавлять их в конец списка и снова List.Sort, но вставить сразу в отсортированный и отсортировать список после вставки. Как мне это сделать? Короче говоря: я не могу использовать SortedList, просто общий список, и я не могу добавить свои элементы в конец MyList1, а затем MyList1.Sort () Мои списки выглядят так:

List<MyClass> MyList1 = new List<MyClass>():
List<MyClass> MyList2 = new List<MyClass>()
MyList1.Sort();

И мне нужны элементы из MyList2, вставленные в MyList1 в том же порядке, в котором они отсортированы. Мой CompareTo() метод, он сортирует по двум свойствам:

public int CompareTo(MyClass next)
{
    int pos = String.Compare(this.name, next.name, StringComparison.CurrentCulture);
    if ((this.price < next.price) || ((this.price== next.price) 
         && (pos > 0)))
    {
        return 1;
    }
    else 
    {
        return - 1;
    }
}

Я понял, как это должно выглядеть, все отлично работает:

static void Inserting(List<MyClass> List1,
           List<MyClass> List2)
        {

            foreach (var item in List2)
            {
                var i = 0;
                while (i < List1.Count && item.CompareTo(List1[i]) > 0)
                    i++;
                List1.Insert(i, item);
            }

        }

Ответы [ 2 ]

1 голос
/ 01 апреля 2019

Если вы хотите вставить его в правильное положение, у вас есть три варианта:

  1. найти правильную позицию, затем Insert это там
  2. используйте предварительно отсортированный список, например SortedList<TKey,TValue> или SortedSet<T> (в зависимости от ваших потребностей) и просто добавьте (примечание: SortedList<TKey,TValue> требует уникальных ключей; SortedSet<T> применяет уникальные значения)
  3. просто AddRange() второй список и снова вызову Sort()

Проблема с «1» заключается в том, что найти правильную позицию для каждого нового элемента эффективно неудобно. Если бы это был массив, вы могли бы использовать Array.BinarySearch - он возвращает побитовое дополнение соответствующего индекса, если совпадение не найдено. Вы можете реализовать бинарный поиск для List<T> вручную, но ... это неинтересно. Для 1 вы захотите использовать BinarySearch, который существует в списке (спасибо @mjwills ), отмечая, что возвращаемое значение, когда совпадение не найдено, является побитовым дополнением, которое сообщает вам, куда его вставить. Но вам все равно нужно будет сделать это для каждого элемента, который складывается.

Лично меня бы соблазнил SortedSet<T> или просто позвонив AddRange() + Sort() на List<T>

0 голосов
/ 01 апреля 2019

Вы можете переопределить метод List Add и сделать это, как показано в примере ниже

public class MyClass : IComparable<MyClass>
{
    public string Name
    {
        get;
        set;
    }
    public int Desc
    {
        get;
        set;
    }

    public int CompareTo(MyClass other)
    {
        return Name.CompareTo(other.Name);
    }
}

public class MyList<T> : List<T> where T : IComparable<T>
{
    public new void Add(T item)
    {          
        if (base.Count == 0)
        {
            base.Add(item);
            return;
        }
        if (base[base.Count - 1].CompareTo(item) <= 0)
        {
            base.Add(item);
            return;
        }
        if (base[0].CompareTo(item) >= 0)
        {
            base.Insert(0, item);
            return;
        }
        int index = base.BinarySearch(item);
        if (index < 0)
            index = ~index;
        base.Insert(index, item);
        base.Add(item);
    }
}


   static void Main(string[] args)
    {
        MyClass myClass = new MyClass();
        myClass.Name = "B";
        MyClass myClass1 = new MyClass();
        myClass1.Name = "A";
        MyClass myClass2 = new MyClass();
        myClass2.Name = "C";
        MyClass myClass3 = new MyClass();
        myClass3.Name = "A";
        MyList<MyClass>mylist= new MyList<MyClass>();

        mylist.Add(myClass);
        mylist.Add(myClass1);
        mylist.Add(myClass2);
        mylist.Add(myClass3);
        Console.ReadKey();
    }

mylist всегда будет отсортирован здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...