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

    +138

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    public static byte[] Trim(this byte[] origin_array)
            {
                int findex = -1, eindex = -1;
    
                bool inseq = false;
    
                if (origin_array[0] != 0x00)
                {
                    if (origin_array[origin_array.Length - 1] != 0x00)
                        return origin_array;
                    findex = 0;
                }
    
                for (int i = 0; i < origin_array.Length; i++)
                {
                    if (origin_array[i] == 0x00)
                    {
                        if (inseq)
                            continue;
                        else
                            inseq = true;
                    }
                    else
                    {
                        if (inseq)
                            if (findex == -1)
                                findex = i;
                        eindex = i;
                    }
                }
    
                if (findex == eindex)
                    return new byte[0];
                
                byte[] result_array = new byte[eindex - findex + 1]; 
                Array.Copy(origin_array, findex, result_array, 0, result_array.Length);
                return result_array;
            }

    Запостил: dzzpchelka, 04 Октября 2014

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

    • А в чем, собственно, говно то? Единственное что, можно было в одну строку написать это все
      return origin_array.Where(x => x != 0x00).ToArray();
      Ответить
      • Я надеялся узнать из комментариев. У меня при взгляде на это почему-то возникает стойкое чувство отвращения. Код мой.
        Ответить
        • Код не тестил, но выглядит правильным. Велосипедненько
          Ответить
        • Ну, код делает не то же самое, что трим делает для строк, но может так и надо?
          if (inseq)
              continue;
          else
              inseq = true;

          эквивалентно:
          if (!inseq) inseq = true;

          или
          inseq ||= !inseq;

          или
          inseq = true;

          Свойство такого кода называется idempotency (не знаю, как по-русски, но смысл в том, что это преобразование, которое можно сделать только один раз, все последующие попытки выполнить те же действия над результатом ничего не изменят).

          Ну и лишние переменные. Если функция должна была себя вести как аналог для строк, то имело бы смысл организовать два счетчика: один считает от начала, другой - от конца, и считать пока они не встретятся.

          А вообще на Стековерфлоу есть секция код-ревью.
          Ответить
          • public static byte[] Trim(this byte[] originArray)
                    {
                        int f = 0, e = originArray.Length;
                        var acc = true;
            
                        while ((f < e) & acc) acc &= (originArray[f++] == 0);
                        acc = true;
                        while ((f < e) & acc) acc &= (originArray[--e] == 0);
                        
                        if (originArray[--f] == 0) return new byte[0];
                        
                        var resultArray = new byte[e - f + 1];
                        Array.Copy(originArray, f, resultArray, 0, resultArray.Length);
                        return resultArray;
                    }
            Ответить
            • Слишком низкоуромненько для меня. Но работает немного быстрее. http://ideone.com/B6rVIl
              Ответить
              • а вообще даже так

                public static byte[] Trim(this byte[] originArray)
                        {
                            int f = 0, e = originArray.Length-1;
                
                            while ((f < e) & (originArray[f++] == 0));
                            while ((f < e) & (originArray[e--] == 0));
                            
                            if (originArray[--f] == 0) return new byte[0];
                            
                            var resultArray = new byte[e - f + 2];
                            Array.Copy(originArray, f, resultArray, 0, resultArray.Length);
                            return resultArray;
                        }
                Ответить
                • Падает. http://ideone.com/B6rVIl
                  Ответить
                  • public static byte[] Trim(this byte[] originArray)
                            {
                                int f = 0, e = originArray.Length;
                    
                                while ((f < e) && (originArray[f++] == 0));
                                if ((--f + 1) != e)
                                    while ((f < e) && (originArray[--e] == 0));
                                else return new byte[0];
                                var resultArray = new byte[e - f +1];
                                Array.Copy(originArray, f, resultArray, 0, resultArray.Length);
                                return resultArray;
                            }



                    ps - чет я седня притормаживаю

                    http://ideone.com/b2xuHN
                    Ответить
                    • На старт, внимание... специальная олимпиада марш!
                      zeros([]).
                      zeros([0 | Xs]) :- zeros(Xs).
                      trim_left([X | Xs], [X | Xs]) :- X \= 0.
                      trim_left([0 | Xs], Ys) :- trim_left(Xs, Ys).
                      trim_right(Xs, []) :- zeros(Xs).
                      trim_right([X | Xs], [X | Ys]) :- trim_right(Xs, Ys).
                      trim(X, Y) :- trim_left(X, Z), trim_right(Z, Y).
                      
                      % | ?- trim([0, 0, 0, 1, 1, 0, 0, 1, 0, 0], X).
                      % trim([0, 0, 0, 1, 1, 0, 0, 1, 0, 0], X).
                      
                      % X = [1,1,0,0,1] ? 
                      
                      % yes
                      Ответить
                      • [оффтоп]Каким интерпретатором пролога пользуешься под линухой?[/оффтоп]
                        Ответить
                        • Сейчас читатю Art of Prolog Programming - вот решил углубиться, до этого иногда пользовался GNU Prolg, сейчас - SWI, но я не знаю таких тонкостей как отладчик / библиотеки и т.п. Слышал, что те, кто используют для настоящих проектов пользуются SWI. Пробовал Mercury, интересно, но иногда есть глупости всякие, особенно связаные с типами, когда например, предикат определен так, что его хрен используешь изза того, что тип по факту совпадает, а по ярлыку - нет. Но, с другой стороны, там есть много интересного, типа автоматического параллелизма и включения в систему типов количественных свойств ответов. Т.е. если одно правило генерирует одно, одно и больше, ни одного и больше, один или ни одного ответов, эту информацию нужно включить в тип (но с другой стороны, это сродни Ява чекед исключениям - вроде есть интересные случаи, когда это нужно, но с другой сторны - чаще хотелось бы не указывать такие подробности).
                          Ответить
                • Nothing
                  Ответить
                  • var resultArray = new byte[e - f + 3];
                    Array.Copy(bArray, --f, resultArray, 0, resultArray.Length);

                    Скорее всего так, иначе первое значение обрезается.
                    Ответить
                • Поставь проверку if(f==e) после первого цикла и выкинь лишнее условие из второго, а заодно if с пустым массивом.
                  UPDATE: f>=e, а то можно пустой массив передать...
                  И почему &, а не &&?
                  Ответить
                  • потому что я тут бегаю делать всякие дела
                    Ответить
          • Новое слово в лексиконе, спасибо за объяснение. Про sof я почему-то забыл.
            Ответить
        • Хотя бы в том, что в одном случае возвращается оригинальный массив, а в другом новый.
          Да и вообще, код можно написать гораздо проще: один цикл по нулям от начала массива, одни так же, но с конца, подвинуть кусок массива к началу и вызвать Array.Resize для отрезания мусора в хвосте. Последние два шага - только если нули были.
          Ответить
          • Изначально нужно было что-бы возвращался новый массив.
            Ответить
        • Да, ещё.
          Антонимы first - last, start - end, left - right. Так что findex - eindex - это странно.
          Отдельная проверка на пустой массив кажется странной, скорее всего, она покрывает какой-то баг.
          Ответить
      • Нет, так из массива пропадут все нули, а не только те что на границах.
        Ответить
        • Был не прав
          return origin_array.SkipWhile(x => x == 0x00).Reverse().SkipWhile(x => x == 0x00).Reverse().ToArray()
          Ответить
          • Оно, конечно, короче, но это еще более говно. http://ideone.com/B6rVIl
            Ответить
            • Эмм, зачем ты это все в for обернул?
              Ответить
              • Серьезно? см. stdout.
                Ответить
                • Ну хорошо)
                  Ответить
                • Просто не очень понятен смысл замеров времене на идемпотентных операциях
                  Ответить
                  • Замеряется время работы каждого метода, и каждый выполняется 50к раз для более очевидных результатов.
                    Ответить
      • во многом
        Ответить
    • Ошибочка вышла
      Ответить

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