1. Java / Говнокод #8089

    +87

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    public static int[] toArray(int i){
    		int[] arr = new int[new String(Integer.toString(i)).length()];
    		for(int j=0;j<new String(Integer.toString(i)).length();++j){
    			arr[j] = Integer.valueOf(new Character(new String(Integer.toString(i)).charAt(j)).toString());
    		}
    		return arr;
    	}

    Запись цифр числа в массив.

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

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

    • Все, беру отпуск на пару дней. Сил моих нет такое видеть
      Ответить
      • Отпуск с говнокода?
        Ответить
      • String chislo = "5748395";
        char [] c = chislo.toCharArray();
        int [] r = new int [c.length];
        int i = 0;
        for (Character ch : c) {
        r[i ++] = Integer.parseInt(ch.toString());
        }
        Ответить
    • Такая простая задача и так много букав...
      // Java
      public static int[] decimals(int n) {
      	String nums = String.valueOf(n);
      	int[] result = new int[nums.length()];
      	for (int i = 0; i < result.length; ++i) {
      	    result[i] = nums.charAt(i) - '0';
      	}
      	return result;
          }
      -- haskell
      decimals :: Int -> [Int]
      decimals = map read . map ( \x -> [x] ) . show
      // Scala
      def decimals(n: Int): Array[Int] = {
          require (n >= 0)
          def iter(x: Int, lst: List[Int]): List[Int] = {
          	if (x == 0) lst
      	else iter(x / 10, (x % 10) :: lst)
          }
          if (n == 0) Array(0)
          else iter(n, Nil).toArray
      }
      Ответить
      • так мала букав и так много CPU & memory usage
        Ответить
        • Java - коду потребуется всего лишь O(log n) памяти в хипе (одна строка и один массив)
          Haskell-код ленивый, памяти нужно мало, скорее всего даже меньше чем джаве
          Scala-код выполняется в постоянном объёме памяти благодаря хвостовой рекурсии, памяти нужно примерно как java-программе.
          Все варианты требуют O(log n) операций
          Ответить
          • Пr'остите мою безграмотность, но как перебор от 1 до n может иметь логарифмическую сложность?

            Или вы имеете ввиду десятичный логарифм? Тогда так и надо писать - lg n. Под log n в IT чаще всего понимают логарифм по основанию 2.
            Ответить
            • http://en.wikipedia.org/wiki/Logarithmic_growth
              Ответить
            • Во-первых, итерация не от 1 до n (обратите внимание, n - входной параметр), а от 1 до количества цифр в числе. А их количество пропорционально логарифму n. При увеличении входного числа n на порядок количество итераций увеличится на единичку.
              Во-вторых, в O-нотации основание логарифма значения не имеет, поскольку домножением на константу можно получить другое основание, а в O-нотации константы значения не имеют. Можете выбрать то основание, которое вам больше нравится.
              Ответить
      • перл:
        sub decimals($) { split//, $_[0] }


        а к слову. на кой такое вообще нужно? разве что для лабы какой...
        Ответить
        • С перлом сравнивать не совсем правильно, там динамическая типизация и неявное приведения типов, в Java/Haskell/Scala строгая типизация.
          Ответить
          • и да и нет. на хаскеле я ожидал чего попроще, т.к. (я надеюсь) есть стандартные функции конвертации в строки, а строки есть списки.

            было бы интересно увидеть правильную реализацию на лиспе.

            ЗЫ по приколу.
            std::list<int>
            decimals(int n)
            {
                    std::list<int> ret;
                    std::stringstream sss;
                    sss << n;
                    std::string x = sss.str();
                    std::back_insert_iterator< std::list<int> > back_it(ret);
                    std::transform( x.begin(), x.end(), back_it, std::bind2nd(std::minus<int>(),48) );
                    return ret;
            }
            Ответить
            • > на хаскеле я ожидал чего попроще
              самое простое, что можно придумать:
              import Data.Char (digitToInt)
              decimals :: Int -> [Int]
              decimals = map digitToInt . show
              Ответить
            • На плюсах как-то сложно получается. Сишечка:
              int* decimals(int n)
              {
                int size = log10(n) + 2;
                int *buf = calloc(size, sizeof(int));
                int i = size - 2;
                buf[size - 1] = -1; // end marker
                while (i >= 0) {
                  buf[i--] = n % 10;
                  n = n / 10;
                }
                return buf;
              }
              Ответить
              • Это бессмысленная занятие, какая-то лаба.
                Но все же. Little Endian
                start: mov eax,98765
                        mov ecx ,10
                        mov ebx,_out
                l1:    cdq
                        div ecx
                ;       add dl,48 ;это нужно для вывода
                        mov [ebx],dl
                        inc ebx
                        cmp eax,0
                jnz l1
                .data
                  _out db '          ',0

                Учите асм и не надо тут выебыватся хаскелами и вычислительными сложностями.
                Ответить
                • > Это бессмысленная занятие
                  Вполне себе похоже на часть задачи с ProjectEuler. Вам не нравится ProjectEuler? :)

                  > Учите асм и не надо тут выебыватся хаскелами
                  Думаете, я никогда не писал на асме? я за портируемый и понятный код.
                  Ответить
                  • >Вам не нравится ProjectEuler? :)
                    Впервые слышу. Но мне больше нравится http://www.mersenne.org/ и Prime95.

                    >я за портируемый и понятный код.
                    А я за быстро работающий на моей машине.

                    Мне становится смешно, когда пишут какой-либо алгоритм на языке с виртуальной машиной, а потом говорят о какой-то "оптимальности" или "заточках".
                    Ответить
                  • Поясню подробней. Первая строка в Вашей java-имлементации.
                    String nums = String.valueOf(n);

                    вызывает
                    public static String valueOf(int i) {
                            return Integer.toString(i, 10);
                        }

                    Integer.toString в свою очередь вызывает
                    public static String toString(int i, int radix) {
                    
                            if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
                    	    radix = 10;
                    
                    	/* Use the faster version */
                    	if (radix == 10) {
                    	    return toString(i);
                    	}
                    
                    	char buf[] = new char[33];
                    	boolean negative = (i < 0);
                    	int charPos = 32;
                    
                    	if (!negative) {
                    	    i = -i;
                    	}
                    
                    	while (i <= -radix) {
                    	    buf[charPos--] = digits[-(i % radix)];
                    	    i = i / radix;
                    	}
                    	buf[charPos] = digits[-i];
                    
                    	if (negative) {
                    	    buf[--charPos] = '-';
                    	}
                    
                    	return new String(buf, charPos, (33 - charPos));
                        }
                    //конструктор new String вызывает
                    public String(char value[], int offset, int count) {
                            if (offset < 0) {
                                throw new StringIndexOutOfBoundsException(offset);
                            }
                            if (count < 0) {
                                throw new StringIndexOutOfBoundsException(count);
                            }
                            // Note: offset or count might be near -1>>>1.
                            if (offset > value.length - count) {
                                throw new StringIndexOutOfBoundsException(offset + count);
                            }
                            char[] v = new char[count];
                            System.arraycopy(value, offset, v, 0, count);
                            this.offset = 0;
                            this.count = count;
                            this.value = v;
                        }


                    и так далее...
                    Повторюсь. Это одна строка кода. String.valueOf(n);
                    Ответить
                    • Итого +1 буфер в 33 символа для хранения результата преобразования и несколько вызовов методов. Да, проще было написать в лоб как на сях, согласен.

                      > говорят о какой-то "оптимальности" или "заточках"
                      Никто не говорит об оптимальности и заточках, только о порядке роста (который зависит только от алгоритма, а не языка реализации), портируемости и читабельности.

                      P.S. Если бы вы проанализировали выполнение приведённого Haskell-кода (где какие thunk'и создаются и т.п.), я был бы вам очень признателен.
                      Ответить
                • А двоично-десятичная арифметика не поможет?
                  Ответить
                • можно прыжок сделать после div (скопипастив хвост за продолжение цикла), сэкономишь сравнение.
                  Ответить
              • да это я на крестах просто извернулся. я СТЛными "алгоритмами" в продакшн коде принципиально (по религиозным соображениям) не пользуюсь.
                Ответить
                • А можно узнать откуда взялась такая религия?
                  Ответить
              • Неоптимально. calloc (заполнение нулями), лишние переменные (size и i — хватит одной), деление можно было бы n /= 10. Если уж писать на C, то от плавучки можно было избавиться. Не работает для 0.
                Ответить
                • Кстати да, про каллок - сишка нового стандарта умеет int a[n], эн - не константа. Ура в сишке теперь есть фича которая была кажись ещё в виртовом паскале в 70м.
                  Ответить
                  • >сишка нового стандарта
                    C99 не такой уж и новый...
                    Ответить
                  • Как раз в классическом Паскале размер массива был составной частью типа. А значит, ни объявить локальный массив переменного размера, ни передать его в функцию, ни возвратить, было нельзя. Это был один из главных пунктов (справедливой) критики Паскаля Керниганом.

                    Появилась эта фича только в Турбо-Паскале, да и то довольно поздно, в 5-й или 6-й версии.
                    Ответить
                    • Я не про турбу.

                      http://books.google.ru/books?id=4LMtA2wOsPcC&pg=PA354&printsec= frontcover&hl=ru&source=gbs_ge_summary_r &redir_esc=y#v=onepage&q&f=false

                      Прокрути чуть ниже, начиная с Conformant Arrays

                      внизу страницы 355

                      Ну и как видишь, то, что размер - часть типа, не отменяет массивов неизвестной длины.
                      Ответить
                      • Там как раз и говориться: Ранний Паскаль… Стандартный Паскаль… А это уже десятилетия спустя. Кстати, где ссылка на Стандарт, с указанием пунктов и подпунктов?
                        Ответить
                      • там ни хуа не видно, дай нормальную варезную ссылку
                        Ответить
            • > было бы интересно увидеть правильную реализацию на лиспе.
              (write-to-string 42)

              Но есть нюанс: знак тоже будет записан, в Лиспе числа теоретически бесконечной разрядности.
              Ответить
              • Насколько я понял, этот код просто генерирует строку символов, а не список чисел.
                Ответить
                • Нет, символы в Лиспе это все тело программы, кроме чисел и зарезервированых выражений (скобок, запятых, кавычек и т.п.), но часто символами называют ключевые слова (т.е. символы которые определены в keywords package, и которые eval'ятся сами в себя). Например,
                  (with-open-file (stream filepath :direction :input) ...)
                  :direction и :input - символы (ключевые слова). character можно рассматривать как численный тип, у которого задан radix, но если это неудобно, то можно воспользоваться вариантом ниже.
                  Ответить
                  • Я знаю, что такое "символы" в CL. Под символами я имел в виду символы в обычном их понимании: элементы строкового типа.
                    Ответить
            • Или, если нужно было преобразовать в какой-то другой численный тип:
              (map 'vector 'char-code (write-to-string 1234567890))
              Ответить
              • спасибо.
                Ответить
              • Как я и ожидал, этот код возвращает совсем не то, что нужно:
                #(49 50 51 52 53 54 55 56 57 48)
                Ответить
                • Ну я это говорю, к тому, что проблема не в алгоритме, а в понятиях, которыми оперирует язык. У некоторых популярных Лиспов есть класс fixnum, но он не входит в стандарт. С помощью этого класса можно было бы эмулировать то, что делает Ява-функция из примера выше, но только до определенной степени, потому, что хотя и Ява и Лисп схожи в том, что чтение за пределами массива вызывает ошибку, строка находится в других отношениях с массивом в Лиспе, нежели в Яве.

                  А вот еще вариант, специально для этого сайта:
                  (defun split-int (x)
                    (map 'vector 
                         (lambda (y)
                  	 (cdr 
                  	  (assoc y '((#\0 . 0)
                  		    (#\1 . 1)
                  		    (#\2 . 2)
                  		    (#\3 . 3)
                  		    (#\4 . 4)
                  		    (#\5 . 5)
                  		    (#\6 . 6)
                  		    (#\7 . 7)
                  		    (#\8 . 8)
                  		    (#\9 . 9)))))
                         (write-to-string x)))

                  :P

                  PS. А что нужно-то было? Я char-code просто как пример написал, можно что угодно другое, это не важно.
                  Ответить
                • Я вдруг подумал, что намек не оценят....
                  (defun split-int (x)
                    (map 'vector 
                         (lambda (y)
                  	 (cdr 	    ;(\____(\
                  	  (assoc y '((#\0 . 0)
                  		    (#\1 . 1)
                  		    (#\2 . 2)
                  		    (#\3 . 3)
                  		    (#\4 . 4)
                  		    (#\5 . 5)
                  		    (#\6 . 6)
                  		    (#\7 . 7)
                  		    (#\8 . 8)
                  		    (#\9 . 9)))))
                         (write-to-string x)))
                  Ответить
      • >haskell
        decimals = map Data.Char.digitToInt . show

        fixed
        Ответить
    • Нет, ну это уже слишком.
      Ответить
    • показать все, что скрытоКто нибудь видел такой сайт, где можно подобрать фильмы по дате и жанру. Допустим я хочу выпущенные фильмы 2011 года, боевики - и получаю список. Качать знаю где rutracker.org . Google выдает один мусор, не могу найти...
      Ответить
    • Ёбаный пиздец, до чего жабство доводит...
      Ответить
    • показать все, что скрытоvanished
      Ответить

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