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

    +147

    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
    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
    public class Matrix {
    
        private float matrix[][];
        private int dim;
    
        public Matrix(int dim) {
            this.dim = dim;
            this.matrix = new float[dim][dim];
        }
    
        public void productOfTwo(Matrix src, Matrix dest) {
            if (src.dim == this.dim) {
                dest.dim = this.dim;
    
                Matrix[] temp = new Matrix[this.dim];
                for (int i = 0; i < this.dim; i++) {
                    temp[i] = new Matrix(this.dim);
                }
    
                for (int i = 0; i < this.dim; i++) {
                    for (int j = 0; j < this.dim; j++) {
                        for (int k = 0; k < this.dim; k++) {
                            temp[k].matrix[i][j] = this.matrix[i][k] * src.matrix[k][j];
                        }
                    }
                }
              
                for (int i = 0; i < this.dim; i++) {
                    dest.sum(temp[i]);
                }
            } else {
                System.out.println("  An error occured: Dimensions of matrices do not match");
            }
        }
    
        public float findDet() {
            if (this.dim == 1) {
                return this.matrix[0][0];
            } else if (this.dim == 2) {
                return this.matrix[0][0] * this.matrix[1][1] - this.matrix[0][1] * this.matrix[1][0];
            } else {
                float result = 0;
                Matrix minor = new Matrix(this.dim - 1);
                for (int i = 0; i < this.dim; i++) {
                    for (int j = 1; j < this.dim; j++) {
                        System.arraycopy(this.matrix[j], 0, minor.matrix[j - 1], 0, i);
                        System.arraycopy(this.matrix[j], i + 1, minor.matrix[j - 1], i, this.dim - (i + 1));
                    }
                    result += Math.pow(-1, i) * this.matrix[0][i] * minor.findDet();
                }
                return result;
            }
        }

    Всем доброго времени суток! Прошу к Вашему вниманию алгоритм нахождения произведения двух матриц(умножаем слева направо) и нахождения детерминанта разложением по столбцу(рекурсия). Прошу оценить, по всей строгости.
    Заранее спасибо!

    Запостил: kaspvar, 24 Июля 2011

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

    • >Прошу оценить, по всей строгости.
      У нас тут говнокод, а не бюро советов.
      Ответить
    • > Прошу оценить, по всей строгости.
      РАК.
      Ответить
    • Да ладно, это ж говнокод:
      1. float. no comments.
      2.
      >public void productOfTwo(Matrix src, Matrix dest)
      Вызов этого метода изменяет состояние dest. Здесь просто напрашивается статический фабричный метод, порождающий новую матрицу, либо публичный метод, принимающий на вход одну матрицу и возвращающий новую, типа

      public Matrix product(Matrix other);


      3.
      > } else {
      > System.out.println(" An error occured: Dimensions of matrices do not match");>
      > }
      Это вообще п****ц. Надо кидать эксепшн, а не тихонько писать в вывод сообщение.
      4. Алгоритмы - гавно, если, конечно, размер матриц не 3х3.
      Ответить
    • ихде инициализация массивов, юзернейм?:
      Ответить
      • public Matrix(int dim) - в конструкторе ничего не происходит? не?
        Ответить
        • ну какбе будет у вас матрица с дефолтными нулями в качестве значений, это чтоль профит?
          Ответить
          • Тогда ставьте вопрос корректнее:"Где метод ввода данных матрицы?".
            Объявление и инициализация матрицы присутствует.
            Метод ввода данных отсутствует.
            Ответить
            • ну просто я всегда считал, что matrix = new float[dim][dim]; не есть инициализация, а есть создание (инстанциирование) массива...
              Ответить
              • Ну, float - базовый тип. А вот Float - класс. Если уж на то пошло.
                Ответить
    • Чтобы было внятнее можно и так:
      if (dim == 1) return matrix[0][0];
      if (dim == 2) return matrix[0][0]*matrix[1][1] - matrix[0][1] * matrix[1][0];
      ...//блок вычислений
      return result;

      Хотя я с поиском через разложением по столбцу не знаком (или вру, но забыл) и первые два условия не имеют необходимости и можно занести все в один блок вычислений. Это вопрос так. Ради интереса.
      И еще - где здесь рекурсия? Мб подразумевается что она развернута в цикл, но все таки...
      Ответить
    • 1.Это моя первая программа на Java, и она не может не быть говнокодом.
      2.Мой преподователь это книга + интернет.
      3.Ето не весь класс: все остальные методы
      в том числе и иинициализацию я не выкладывал.
      4.roman-kashityn - спасибо! Переделаю.
      Один вопрос: почему все-таки говно?
      Долго считать будут при больших размерностях?
      5.SmackMyBitchUp - рекурсия запускается в
      49-й строке. Первые два случая: для 2*2 и 1*1 вынесены
      отдельно так как алгоритм для размерности >2
      их посчитать не сможет.
      Ответить
      • О_о то есть у вас в цикле идет вызов функции из нее самой? x_X
        а какова точка останова подскажите, пожалуйста.
        Ответить
        • Что непонятного, в начале функции же концы рекурсии стоят.
          Ответить
      • Эти алгоритмы хороши для теоретических расчётов на бумажке в случае небольших матриц, для практических целей они не подходят. Лучше поищите в инете книжку по вычислительным алгоритмам для матриц, поверьте, человечество уже далеко продвинулось в этом вопросе. С другой стороны, если это просто лаба - не парьтесь особо, реализация и отладка нормального алгоритма займёт приличное время. Это не то место, где стоит обсуждать такие вопросы, и я не самый большой спец. Приходилось, конечно, писать на фортране всякие убийственные вещи, но у меня немного другой профиль.

        И, кстати, обратите внимание на интерфейсы стандартных классов типа BigInteger, они подскажут, как лучше организовать интерфейсы для матриц в плане сигнатур и названий методов.
        Ответить
    • Точкой остановки будет тот момент, когда будет вычислено и (result+=) записано в результат последнее слагаемое разложения.
      Чтобы собственно вычислить определитель разложением по определению нужно: выбрать строку/столбец,
      1.взять оттуда каждый элемент,
      2.умножить его на алгебраическое дополнение(знак*минор элемента),
      3.и сложить все слагаемые.

      Тут мы создаем минор элемента:
      for (int j = 1; j < this.dim; j++) {
      System.arraycopy(this.matrix[j], 0, minor.matrix[j - 1], 0, i);
      System.arraycopy(this.matrix[j], i + 1, minor.matrix[j - 1], i, this.dim - (i + 1));
      }
      А здесь собственно умножаем элемент на его алгебраическое дополнение и записываем все в result, который собственно и является определителем матрицы.
      result += Math.pow(-1, i) * this.matrix[0][i] * minor.findDet();
      Здесь рекурсия ->minor.findDet().
      Зачем вызывать findDet() в цикле? Думаю, это лучший вариант сложить все слагаемые строки/столбца в result, как можно быстрей.
      Ответить
    • vanished
      Ответить

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