Jawa / Говнокод #7711 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
public class Sorting {  

    private static void swapElements(int[] arr, int index1, int index2) {
        int temp = arr[index1];
        arr[index1] = arr[index2];
        arr[index2] = temp;
    }

    public static void mergeSort(int[] arr) {
        if (arr.length == 1) {
            return;
        }        
        final int temp = (arr.length % 2 == 0) ? arr.length / 2 : (arr.length + 1) / 2;

        int[] left = new int[temp];
        int[] right = new int[arr.length / 2];
        System.arraycopy(arr, 0, left, 0, temp);
        System.arraycopy(arr, temp, right, 0, arr.length / 2);

        Sorting.mergeSort(left);
        Sorting.mergeSort(right);
        Sorting.mergeSortHelper(arr, left, right);
    }

    private static void mergeSortHelper(int[] arr, int[] left, int[] right) {
        int L = 0, R = 0;
        boolean Ltop = false, Rtop = false;

        for (int i = 0; i < arr.length; i++) {
            if (L < left.length - 1 && R < right.length - 1) {
                if (left[L] <= right[R]) {
                    arr[i] = left[L];
                    L++;
                } else {
                    arr[i] = right[R];
                    R++;
                }
            } else if ((L == left.length - 1) ^ (R == right.length - 1)) {
                if (L == left.length - 1) {
                    if ((left[L] <= right[R]) && !Ltop) {
                        arr[i] = left[L];
                        Ltop = true;
                    } else {                        
                        arr[i] = right[R];
                        R++;
                    }
                } else {
                    if ((right[R] <= left[L]) && !Rtop) {
                        arr[i] = right[R];
                        Rtop = true;
                    } else {                        
                        arr[i] = left[L];
                        L++;
                    }
                }
            } else {
                if (i < arr.length - 1) {
                    arr[i] = (left[L] < right[R]) ? left[L] : right[R];                    
                } else {                    
                    arr[i] = (left[L] > right[R]) ? left[L] : right[R];
                }
            }
        }        
    }

Реализация сортировки слиянием на Java

Запостил: kaspvar kaspvar, (Updated )

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

  • Сразу много вопросов:
    1. Зачем?
    2. Почему так много?
    3. Где дженерики? -> Где здесь java?
    Ответить
  • 1. Знать элементарные алгоритмы сортировки нужно обязательно.
    2. Я б-кодер =(
    3. До дженериков еще не дошел.
    Ответить
  • Почему бы не сделать так:
    final int temp = (arr.length + 1) / 2;
    
            int[] left = new int[temp];
            int[] right = new int[arr.length - temp];
    И не переименовать temp в middle?
    И весь mergeSortHelper сомнителен, особенно название, else if и bool'и в нем.
    Ответить
    • К тому же, есть Arrays:
      final int middle = (arr.length + 1) / 2;
      int[] left  = Arrays.copyOfRange(arr, 0, middle);
      int[] right = Arrays.copyOfRange(arr, middle + 1, arr.length);
      Ответить
  • Ни разу не видел нормального кода слияния массивов. Действие, казалось бы, тривиальное,, но его алгоритм всегда выглядит, как говно, с тройными неинтуитивными условиями и причей фигнёй.
    Ответить
    • (defun stupid-merge-sort (seq)
          (if (< (length seq) 2)
              seq
              (let (
                  (middle (truncate (length seq) 2)))
                  (merge (if (listp seq) `list `vector) (stupid-merge-sort (subseq seq 0 middle)) (stupid-merge-sort (subseq seq middle)) #'<))))
      Ня?
      Ответить
      • Так не честно, всё самое интересное уползло в библиотечную merge. С другой стороны, реализовать её довольно просто.
        Ответить
        • честно =)
          mSort([],[]):-!.
          mSort([X],[X]):-!.
          mSort(X,Y):-split(X,H,T),mSort(H,H1),mSort(T,T1),merge(H1,T1,Y).
          
          merge([],X,X):-!.
          merge(X,[],X):-!.
          merge([H1|X],[H2|Y],[H1|R]):- H1 < H2,!,merge(X,[H2|Y],R).
          merge(X,[H2|Y],[H2|R]):- merge(X,Y,R).
          split(X,H,T):- length(X,LenX),append(H,T,X),length(H,LenH),LenH is div(LenX,2).
          Ответить
            • На прологе самое то решать дурацкие задачки.
              Ни ifов ни циклов тебе.
              Ответить
              • Мне haskell нравиться (код писал не я, но я бы написал так же):
                merge [] ys = ys
                merge xs [] = xs
                merge (x:xs) (y:ys) = if x <= y
                                      then x : merge xs (y:ys)
                                      else y : merge (x:xs) ys
                
                mergesort [] = []
                mergesort [x] = [x]
                mergesort xs = let (as, bs) = splitAt (length xs `quot` 2) xs
                               in merge (mergesort as) (mergesort bs)
                Ответить
                • P.S. Хотя нет, третий шаблон для merge надо бы написать по-другому:
                  merge u@(x:xs) v@(y:ys) = if x <= y
                                            then x : merge xs v
                                            else y : merge u ys
                  Ответить
                    • На Форте не нашел, но есть на самом любимом языке Тараса:
                      #include        <iterator>
                      #include        <utility>
                      #include        <algorithm>
                      
                      #include        <deque>
                      #include        <string>
                      #include        <iostream>
                      
                      template <typename SomeIterator, typename SomeCompare>
                          void stupid_merge_sort(SomeIterator begin, SomeIterator end, SomeCompare compare, std::bidirectional_iterator_tag category){
                      
                          typename SomeIterator::difference_type distance = std::distance(begin, end);
                      
                          if((distance > 2) || (distance < -2)){
                              SomeIterator middle = begin;
                              std::advance(middle, distance/2);
                              stupid_merge_sort(begin, middle, compare,  category);
                              stupid_merge_sort(middle, end, compare, category);
                              std::inplace_merge(begin, middle, end, compare);
                          }
                      }
                      
                      template <typename SomeIterator>
                          void stupid_merge_sort(SomeIterator begin, SomeIterator end){
                              stupid_merge_sort(begin, end, std::less<typename SomeIterator::value_type>(), typename std::iterator_traits<SomeIterator>::iterator_category());
                      }
                      
                      template <typename SomeIterator, typename SomeCompare>
                          void stupid_merge_sort(SomeIterator begin, SomeIterator end, SomeCompare compare = SomeCompare()){
                              stupid_merge_sort(begin, end, compare, typename std::iterator_traits<SomeIterator>::iterator_category());
                      }
                      
                      typedef std::deque<std::string> SomeContainer;
                      
                      int main(int argc, char* argv[]){
                          SomeContainer       cont;
                      
                          for(unsigned i = 1; i < argc; i++)
                              cont.push_back(SomeContainer::value_type(argv[i]));
                      
                          stupid_merge_sort(cont.begin(), cont.end());
                      
                          for(SomeContainer::iterator it = cont.begin(); it != cont.end(); ++it)
                              std::cout<<(*it)<<std::endl;
                      }
                      Ответить
                    • Лёгкое гугление даёт такой результат:
                      : merge-step ( right mid left -- right mid+ left+ )
                        over @ over @ < if
                          over @ >r
                          2dup - over dup cell+ rot move
                          r> over !
                          >r cell+ 2dup = if rdrop dup else r> then
                        then cell+ ;
                      : merge ( right mid left -- right left )
                        dup >r begin 2dup > while merge-step repeat 2drop r> ;
                       
                      : mid ( l r -- mid ) over - 2/ cell negate and + ;
                       
                      : mergesort ( right left -- right left )
                        2dup cell+ <= if exit then
                        swap 2dup mid recurse rot recurse merge ;
                       
                      : sort ( addr len -- )  cells over + swap mergesort 2drop ;
                       
                      create test 8 , 1 , 5 , 3 , 9 , 0 , 2 , 7 , 6 , 4 ,
                       
                      : .array ( addr len -- ) 0 do dup i cells + @ . loop drop ;
                       
                      test 10 2dup sort .array       \ 0 1 2 3 4 5 6 7 8 9
                      Ответить
                • я как-то на эрланге пытался это написать в качестве упражнения. получилось не упражнение - а испражнение. не выдержал поглядел как делать правильно - а там такое же испражнение.

                  отсутствие структур данных высокого порядка портит ИМО функциональные языки. уперлись ж религиозно в односвязные списки...
                  Ответить
                  • Что имеется ввиду под структурами данных высшего порядка?
                    Ответить
                  • Не знаю, как в Erlang (он следующий в моей очереди на изучение), но в стандартную библиотеку Haskell входят массивы, бинарные строки, деревья, графы, хэш-таблицы и ещё много всего (разумеется, вместе со стандартными алгоритмами). Неужели всего этого нет в Erlang?
                    Ответить
                    • есть. но большинство реализовано на самом эрланге обычными списками.

                      когда видишь обычную FIFO у которой ассимптотическая производительность O(n) (best case O(1), но в случае FIFO это просто не случается, cue in zippers) то как подталкивает на размышления.
                      Ответить
                      • На том же Lisp на списках легко делается FIFO с асимптотической сложностью O(1). Странно всё это.
                        Ответить
                        • в лисп? FIFO без зипперов? пример в студию: добавление элемента в конец, удаление из начала, оба O(1). (я по лиспу книжку читаю, интересно.)
                          Ответить
                            • реализация использует cdr, который возвращает все элементы массива кроме первого, на основе чего создается новый список -> происходит копирование почти полного списка -> O(N).

                              нету в функциональных языках O(1) оператора для добавления элемента в конец списка.

                              единственное что придумали это зипперы - http://en.wikipedia.org/wiki/Zipper_%28data_structure%29 - но они предоставляют только амортизированую O(1).
                              Ответить
                              • > происходит копирование почти полного списка
                                кто вам такое сказал? можно ссылку на источник? конструирование происходит только с помощью cons (и это операция O(1)), car и cdr - просто селекторы. Они нужны для обхода списка и никоим образом его не модифицируют (разве что только могут появиться объекты, пригодные для сборки мусора). Там же написано: "the queue operations to be implemented so that they require O(1) steps".
                                Ответить
                                • ты похоже прав. я еще тольком с лисповыми переменными не разобрался: они ведь в отличии от хаскеля и эрланга mutable. то что я говорил 100% применимо к эрлангу и если я не ошибаюсь к хаскелю - или обобщенно к языками которые стремятся быть чисто функциональными.
                                  Ответить
                                  • Да, в haskell значения переменных и списки менять нельзя и там такую очередь не напишешь (нельзя будет изменить конец в очереди как в lisp). Там это и не нужно, ибо есть Data.Sequence (чисто функциональный, сорцы можно посмотреть в интернете).
                                    Ответить
                                    • видел. Data.Sequence это finger tree (пальчиковое дерево? лол) работают по принципу подобному zipper, но для организации так же используют lazy evaluation. вообщем: тоже предоставляют только амортизированое время.

                                      лисп из всех этих языков наверное самый мощный, бо не пытается красивым теориям следовать, а остается просто практичным.

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

                                      на хаскель после прочтения пару туториалов я забил, бо очень много теории и сказок о красоте программирования на хаскеле. субстанции очень мало.

                                      а ведь все началась с простого поиска выразительного язычка для быстрого прототипирования...
                                      Ответить
                                      • > выразительного язычка для быстрого прототипирования
                                        python?

                                        Если бы Erlang был не функциональным, его модель акторов была бы в глубокой... яме.

                                        Так-то я пишу на Java. Haskell изучаю ради новых идей... И чтобы свободнее себя чувствовать в Scala. Мне он кажется довольно практичным, но на освоение требуется уйма времени и практики. Хотя Lisp тоже доставляет. Жаль, времени мало на всё.
                                        Ответить
                                        • > python?

                                          отсутствие варнингов + слабая типизация + общая тормознутость не самая лучшая комбинация, к сожалению.

                                          перл иногда тормозит похлеще, но варнинги (что я может чего не то написал что я думал что я написал) кидает сразу. количество встроеных прямо в язык функций тоже как бы развращает: можно по тупому сложные (но вторичные) проблемы делать.

                                          с перлом моя проблема только в том что иногда напишешь прототип, вроде коротко и работает нормально. а когда начинаешь это в С/С++ конвертить... страницы и страницы кода. эстимэйшены времени разработки на основе перловых прототипов делать в принципе невозможно.
                                          Ответить
                                          • Код с Lisp/Erlang конвертить в C/C++ вроде бы вообще задача нетривиальная... C Perl то уж попроще будет. По статистике программа на Perl в 8-10 раз короче программы на C, программа на C++ - в 2 раза короче аналогичной программы на C (так написано у Макконнелла). Вот вам и эстимэйшн 🙂 Конечно, многое ещё зависит от программиста.
                                            Ответить
          • > merge([],X,X):-!.
            А так вообще можно? В смысле, одинаковое имя аргументов.
            Ответить
            • да это означает что если мы мерджим пустой список с X то результат будет X.
              Синтерпретировано в Swi-Prolog
              Ответить
        • (merge <что-то> <кое-что> <что-нибудь> <предикат>)
          Вполне себе код слияния массивов (точнее proper sequences)
          Ответить
      • вот вам на перле самописаное кахдато давно:
        sub merge_sort
        {
        	my ($cmp, @l) = @_;
        
        	return @l if @l <= 1;
        
        	my @l1 = merge_sort( $cmp, @l[0..$#l/2] );
        	my @l2 = merge_sort( $cmp, @l[$#l/2+1 .. $#l] );
        
        	my @ret;
        	while (@l1 && @l2) {
        		if ($cmp->($l1[0], $l2[0])) {
        			push @ret, shift(@l1);
        		} else {
        			push @ret, shift(@l2);
        		}
        	}
        
        	push @ret, @l1 if @l1;
        	push @ret, @l2 if @l2;
        	@ret;
        }
        
        print merge_sort( sub { $_[0] lt $_[1] }, <> );


        неоптимально, ну да и хер с ним. писал только что бы узнать сколько приблизительно строк (по сравнение с С вариантом) на Перле будет.
        Ответить
    • я бумажку по дуал пайвоту качнул но еще не читал. но выглядит так как если бы всех проблем qsort он не решает, а только уменьшает вероятность деградации производительности.

      другими словами: везде где важна ассимптотическая (не абсолютная!) производительность, все равно надо мерж сорт писать.
      Ответить
  • б"Y!H"U!T?T)B MS:O)D$F"R,T K H K:M$J(F)F(X"X)A(X(P)Z F"H.W,TT:U)Q X,P?J E.G"Q.V(O(TTY(C)Z,P?F$H P$H.V)I,J$Z!C(V,E"M?JC:M$N$K?V)V$E MA H$GT)Y"W.C"K(B$X!H$I?B)T!S"N?M:X!A$H"K(C.T.X$K$Y:D Y"O)W?W.A:N?R.L"N?K:EG!D)R.Y)H,Y"G!G"T!H$S$Z O K"Z M,T)NF!Q.V(X(C R(T$E?I?D"J.M(L,P.U)LM"Z!L)C.L U!S.R W,I:W!X"Q Z,O:U,C.Z.D(U"K)D:A:O"V"G"O?D!B!X!Z?A(F I:L)G)U$K.H,LD"U.YQ.G.J X:Q.V!F"Z?P!W!O(Z.R:UG:T$H C$Q!U)W"N.OX)O$P,G(G(A,F"U)Q.C.ZN,R:Z T"D$X:D$O?C I(X:S B,S,M(N!Y.F C)T)YX?H:A)W,F E:M!SU$L,WLH:B?I!Z.Z(R,E$A(E.JG"N"S(J"U A$R(HL S,I$G:XGI"Z,J,N:P.O(NQ)N:Z.N"R,R$C(I!EP(O?J(E$Q R.V L(I$V:O!C.JEV:R"L$AY,S?D$U)N:P(DШWHQDUESZFBHBIDJHYWYXFUIZSBBJEKVAKSJULQRKCWPMNZJJCYSBOCQCSIXCXTEZNIFHNXEQBRVBBFOGCHQWDSBVFUNWSCSEHEUYTNMPBOWEWQNEULGHESUVTNNMCMOPWWQADDMUQUXLRRSNGXDQZYUXAZYOXZBAGRGUEDVKVOLIPISCMTOOMOWBMRBBEUURUDMNTEDNPRJUBHFEHYIVJEVWDTSMEZAAPJZSXVAVDBBFWKZROVULDODPGGXZQJOBSAYFFVFEWCFTDHTSIMBFPNPNGXQMMTUIA
    Ответить

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

Из-за тебя ушел bormand, guest!

    А не использовать ли нам bbcode?


    8