1. C# / Говнокод #13589

    +124

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    for (var i = 0; i < Collection.Count(); i++)
                    {
                        if (i==x)
                        {
                            Collection.Remove(i);
                        }
                    }

    Классика

    Запостил: kegdan, 09 Августа 2013

    Комментарии (84) RSS

    • Не то написал)

      for (var i = 0; i < Collection.Count(); i++)
                      {
                          if (Collection[i] == x)
                          {
                              Collection.Remove(Collection[i]);
                          }
                      }


      А то получился совсем говнокод говнокода)
      Ответить
      • может все-таки
        if (Collection[i] == x)
        {
          Collection.Remove(Collection[i]);
        }
        Ответить
        • if (Collection[i] == x)
          {
          Collection.Remove(i);
          }
          Ответить
          • в вашем случае нужно
            if (Collection[i] == x)
            {
            Collection.RemoveAt(i);
            }

            http://msdn.microsoft.com/ru-ru/library/ms132413.aspx
            Ответить
      • а если
        Collection.Remove(x);
        не прокатит? :)
        Ответить
        • а вдруг Remove(), как в питоне, удаляет только первое вхождение..
          Ответить
          • да, только первое.

            Вообще правильное удаление будет выглядеть так

            Collection.RemoveAll((collectionElement) => collectionElement == x);

            Главная загвоздка говнокода - он не удалит все вхождения Х.
            Ответить
            • while (Collection.Remove(x) != %somethingThatWillBeReturnedWhenTereIsNoSuchElement%) ;
              Не?
              Ответить
              • Это же уздец

                вот пример входной коллекции
                1,...,1(примерно 10000 элементов)2,2,2,2,2.

                Начинаешь ты удалять все вхождения двойки.
                Он найдет первую и начнет искать сначала.
                сколько раз он пройдет по всем единицам?

                расово верный цикл для удаления
                var i = 0;
                                while (i < Collection.Count())
                                {
                                    if (Collection[i] == x)
                                        Collection.RemoveAt(i);
                                    else i++;
                
                                }
                Ответить
            • А зачем нужен метод, удаляющий только первое вхождение, и почему нет метода, удаляющего все?

              И главное: worst case O(n^2). Не проще ли копию создать одним выражением linq?
              Ответить
              • Да хоть как можно. Даже так извратится

                var newCollection = Filter(Collection, x, (elem,removable)=>elem!=removable);
                ...
                private IEnumerable<T> Filter<T>(IEnumerable<T> collection, T Element, Func<T,T,bool> filterСondition)
                        {
                            foreach (var collectionElement in collection)
                            {
                                if(filterСondition(collectionElement, Element))
                                {
                                    yield return collectionElement;
                                }
                            }
                        }

                Ответить
                • Кстати, а в сисярпике есть как linq, но который возвращает enumerable? В фитоне есть списковые выражения, которые возвращают список, и генераторные, которые возвращают, внезапно, генератор.
                  Ответить
                  • Насколько я знаю linq все превращает в IEnumerable. Даже небо, даже Аллаха. А потом конверть во что хочешь
                    Ответить
                    • Ну так охуенно. Всего лишь надо написать на линкуэ аналог
                      (t for t in collection if t != x)
                      Ответить
                      • var newCollection = from collectionElement in Collection where collectionElement!=x select collectionElement;


                        Но с RemoveAll красивее
                        Ответить
                        • O(n^2)?
                          Ответить
                          • O(n)
                            Пруф
                            http://msdn.microsoft.com/ru-ru/library/wdka673a.aspx
                            Ответить
                            • O(n) вызовов коллбека, а замена одного элемента без выделения памяти будет за O(размер списка), ибо сдвиг, замена всех - O(размер списка ^ 2) в худшем случае.
                              Ответить
                              • В вашем говноязыке можно это сделать за O(n) с минимальный ценой n=1. Ничего не надо удалять - надо добавлять в новый, и возвращать его. Т.к. прямых указателей в вашем говноязыке нет - у вас указатели не сломаются, да и их вообще наверное в вашем говно ПЯП нет.
                                Ответить
                                • >без выделения памяти
                                  Читать умеешь?
                                  Ответить
                                  • Очередной питух, какое нахрен выделение памяти? Ты упоролся? Иди проспись - тебе ничего не мешает сделать за O(n) с перемешением елементов без "выделений".

                                    И да, питушок, на уровне ВМ выделение памяти ничего не стоит, а в нормальном коде они бесплатны. Ты не путай уровень говно, на котором ты, говно, пишешь говно и уровень ВМ.
                                    Ответить
                                    • К слову, в шарпике можно работать напрямую с памятью в unsafe блоке, но мало и неинтересно
                                      Ответить
                                      • Не смеши мои тапки - напрямую. Из вас никто даже матчасти не знает, какое вам напрямую?

                                        Да не нужно это, зачем мне что-то делать через жопу - когда я беру сишку и юзаю сисколы? С памятью и в паскале типа можно работать, но это "эмуляция", жалкая эмуляций, а не работа с памятью, но т.к. никто из вас матчасти не знает - для вас это "работа напрямую".
                                        Ответить
                                        • "напрямую" это записать байт по определенному адресу, сиречь заставить процессор сделать mov.

                                          Что мешает делать это на том же паскале -- не понятно.

                                          Также не понятно зачем тут сисколы (это про brk чтоль?), не говоря уже о том, что сисколы не переносимы
                                          Ответить
                                      • > мало и неинтересно
                                        Действительно, неинтресно. Хочешь сишкоблядствовать? Пиздуй на си.
                                        Ответить
                                        • Анскильных питушков я не спрашивал, так-то.
                                          Ответить
                                          • >Ко-ко-ко
                                            Дада, иди на работу - байтики двигать. Раз-раз-раз.
                                            Ответить
                                            • Вот и встретились 2 одиночества...
                                              Ответить
                                            • Вторая слилась.
                                              Ответить
                                              • >слилась
                                                В твоих влажных мечтах, Манька.
                                                Ответить
                                                • Питушок, я тебе привел алгоритм байды без выделения памяти - ты начал что-то кукарекать. Кукарекая про "выделение памяти" - ты уже животное.
                                                  Ответить
                                                  • >Добавлять в новый
                                                    Это не выделение, пидорва?
                                                    Ответить
                                                    • Нет, питух. Иди учи матчасть. Ничего не мешает новым использовать предидущий, да и говно - ты упоролся, какое нахрен выделение памяти? Иди учи матчасть животное.
                                                      Ответить
                                                      • Кому новым использовать что предыдущий? Петуз?
                                                        Ответить
                                                        • В хламину слилась балаболка, для тебя на пальцах объясню, говно:

                                                          1, 2, 3, 2, 4, 1, 3, 1 - твоя байда, тебе надо выпилить все еденицы - пудумай своей одно извилиной - как это сделать за O(n).
                                                          Ответить
                                                          • > как это сделать за O(n).
                                                            Элементарно ;) Но писать решение не буду, вопрос все таки не ко мне был...
                                                            Ответить
                                                            • > писать решение не буду
                                                              Вчера kegdan уже привёл вариант решения
                                                              http://govnokod.ru/13589#comment191188
                                                              Правда, для плюсов в общем случае нужен код похитрее.
                                                              Ответить
                                                              • Осилил бы он ещё матчасть, а потом выкинул бы этот говнопсевдоЯП - было бы лучше, а так питушня.
                                                                Ответить
                                                                • > выкинул бы этот говнопсевдоЯП
                                                                  http://ideone.com/RuooN4
                                                                  Царь, исправьте анскильный недокод на православной няшке своей всемогущей дланью.
                                                                  Ответить
                                                                • Мудло колхозное, если не осилил ЯПВУ закрой рот и не тяфкай.
                                                                  Тут без оленей вроде тебя все знают как за O(n) по времени и памяти отфильтровать список. Иди лови сегфолты и мемори корапты, чмо.
                                                                  Ответить
                                                                  • > Мудло колхозное, если не осилил ЯПВУ закрой рот и не тяфкай.
                                                                    Спокойствие, только спокойствие... от чего у вас случился такой огненный баттхерт?
                                                                    Ответить
                                                                  • @Belorus мухахаха, достойный оппонент Царя. Царь, а действительно, что, неасилил? Скушно писать обход на ЯВУ без сегфолтов, надо попердолиться сишкой. Нет, сишка нужна, но там, где то же самое нельзя сделать на более высокоуровневом языке, и это ты, Царь, должен обосновывать нужность своей говносишки, как заведомо более убогого средства для всего, кроме какой-то выдуманной полуебком синтетики ради презентации его псевдоскиллов.
                                                                    Ответить
                                                                  • >Иди лови сегфолты и мемори корапты, чмо.

                                                                    На такое следует отвечать "иди лови стопзеворлдные GC, хранение четырёх байт в куче, и ручное управление ресурсами"
                                                                    Ответить
                                                                • Какой багор )))
                                                                  Ответить
                                                                • Анскильная лалка.
                                                                  Ответить
                                                                • Ты питух ты анскильный. Сложность алгоритма не зависит от языка. Ты просил за O(n) сделать, а не на нормальном языке.
                                                                  Ответить
                                                                • Да пошёл ты нахуй.
                                                                  Ответить
                                                          • я ж вроде решение показывал, или не годится?
                                                            Ответить
                                                            • > не годится?
                                                              почти нормально, но царь не приемлит нецарских языков, а хочется увидеть его вариант.
                                                              Ответить
                                                          • > пудумай своей одно извилиной

                                                            Ты забыл сказал «пужулуйста».
                                                            Ответить
                                                  • Где ты привёл, питушок? Я весь тред перечитал - нихуя не понял о чём спор.
                                                    Ответить
                                          • Они и не отвечают.
                                            Ответить
                              • Никаких сдвигов нет, это же генератор по сути.
                                Ответить
                              • >поэтому данный метод является операцией O(n)
                                честно говоря я не думаю, что там банальный цикл.

                                Фиг его знает. На мсдн что у remove, что у removeAll стоит o(n). Думаю они бы написали что то вроде "Данный метод юзает обычный remove, почему o(n*n), будь внимателен, анонимус".

                                Хотя - эо же мсдн, там ничему верить нельзя)
                                Ответить
                                • removeAll() таки за O(n) выполняется.
                                  Чтобы в этом убедиться создайте большой массив заполненный одним и тем же числом. Например, на 1е6 элементов. Удаляет мгновенно, явно не за квадрат.
                                  Ответить
                                  • Да линейный алгоритм removeAll() вообще несложно реализовать даже для ArrayList.
                                    Ответить
                                    • И я о том же. Все-таки в microsoft умеют писать код.

                                      >Да линейный алгоритм removeAll() вообще несложно реализовать даже для ArrayList.

                                      Просто переписывать элементы по ходу. После каждого подходящего для удаления смещение увеличивается. а потом удаляются из конца N элементов.
                                      Ну это я на вскидку решение предложил.
                                      Ответить
                                  • Для пущей важности можно и замерить
                                    Ответить
                • > Да хоть как можно. Даже так извратиться
                  Grammar-nazi к вашим услугам.
                  Ответить
              • Мыши плакали, кололись, но продолжали пользоваться методом, удаляющим только первое вхождение.
                Ответить
    • Не понимаю, как работает этот ремув:
      List<int> lst = new List<int>();
      lst.Add(4); lst.Add(5); lst.Add(5); lst.Add(6); lst.Add(5);
      for (int i = 0; i < lst.Count; i++){
      if (lst[i] == 5) {
      lst.Remove(5);
      System.Console.Write(i + " ");
      }
      }
      вывод: 1, 3. Ну да, логично: удаляется пятерка с индексом 1, потом происходит "смещение" списка влево, то есть у второй пятерки индекс стает равным 1;
      дальше i == 2, lst[i] == 6 -- ничего не удаляем, i == 3 и удаляется последняя пятерка.
      System.Console.WriteLine();
      for (int i = 0; i < lst.Count; i++){
      System.Console.Write(lst[i] + " ");
      вывод: 4 6 5.
      Т.е. мы последнюю пятерку не удалили. Как так?
      Ответить
    • Мне кажется вы не поняли сути говнокода. Вот вам пример наглядный
      http://ideone.com/lLNdLI
      Ответить
      • Итерация по модифицируемой коллекции? Действительно, классика.

        Вроде как с foreach бы исключение вылетело при модификации колекции?
        Ответить
        • Да, при использовании foreach элементы коллекции дублируются в локальные переменные readonly.
          Ответить
    • Никто похоже не обратил внимания на Collection.Count() вместо Collection.Count. Тут подвох в том, что без скобок это было бы свойством коллекции (у большинства коллекций оно есть) и выполнялось за O(1), а вот со скобочками - это вызов метода linq, который означает, что на каждой итерации цикла он будет полностью пробегаться по списку, чтобы узнать его длину. Это уже O(n^2) независимо от числа удалений *ROFL*
      Ответить
      • И это в том числе. Кстати, это жутко бесит. Раньше все время забывал, что у массива не count а length и писал count() ибо линк позволяет
        Ответить
    • var Collection = new List<int>() { 1, 1, 1, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 3, 1 };

      for (var i = 0; i < Collection.Count; i++)
      {
      Collection.Remove(1);
      }
      разве этого не достаточно? remove(x) на каждой итерации будет удалять первое вхождение которое равно x, в данном случае x = 1
      Ответить
    • Охуеть, кто апнул тред Царя?
      Ответить

    Добавить комментарий