Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > помогите с реализацией матриц


Автор: kosmonaFFFt 18.9.2008, 18:58
Доброго всем времени суток.

Понадобился мну сегодня класс МАТРИЦА, в котором было бы реализовано умножение этих самых матриц.
И решил я сделать так:
Код

package project2;

import java.util.ArrayList;

public class FMatrix extends ArrayList<ArrayList<Integer>> {
    
    //Конструктор. Принимает размер и начальное значение элементов матрицы.
    public FMatrix(Integer linesCount, Integer columnsCount, Integer initialValue) {
        super();
        for (Integer lineNumber = 0; lineNumber < linesCount; ++lineNumber) {
            this.add(new ArrayList<Integer>());
            for (Integer columnNumber = 0; columnNumber < columnsCount; ++columnNumber) {
                this.get(lineNumber).add(initialValue);
            }
        }
    }
    
    //Умножение матриц.
    public static FMatrix MultiplyMatrix(FMatrix left, FMatrix right) throws MultiplyMatrixException {
        if (left.get(0).size() != right.size()) {
            throw new MultiplyMatrixException("Ошибка умножения матриц!!! Несоответсвие размера!!!");
        }
        FMatrix result = new FMatrix(left.size(), right.get(0).size(), 0);
        for (Integer lineNumber = 0; lineNumber < left.size(); ++lineNumber) {
            for (Integer columnNumber = 0; columnNumber < right.get(0).size(); ++columnNumber) {
                for (Integer index = 0; index < right.size(); ++index) {
                    //И вот тут то и закрался подвох.
                    //======================================================================================
                    result.get(lineNumber).get(columnNumber) += left.get(lineNumber).get(index) * right.get(index).get(columnNumber);
                    //======================================================================================
                }
            }
        }
        return result;
    }
}


И при реализации умножения столкнулся с проблемой - метод ArrayList<Integer>.get(index) возвращает значение, а не ссылку и элемент матрицы нельзя изменить. (здесь я могу ошибаться)
Сообщение об ошибке:
Код

required: variable
found   : value

Прошу помощи -> (как это можно обойти) || (сделать по другому без лишних телодвижений).

Заранее спасибо.

Автор: duk 18.9.2008, 22:25
Там еще set есть.

Автор: polosatij 18.9.2008, 22:43

ты очень сложно решение задачи написал.. я бы на твоём месте, сначало всё упростил..


Цитата(kosmonaFFFt @  18.9.2008,  18:58 Найти цитируемый пост)
метод ArrayList<Integer>.get(index) возвращает значение,


ArrayList<Integer>.indexOf('Object') даст index
ArrayList<Integer>.set(index, 'new Object') посадит Объект на нужное место..

надеюсь понятно объяснил и в тему, т.к. не стал смотреть твоё задание целиком, ты перемудрил сильно..

Автор: kosmonaFFFt 19.9.2008, 09:53
Цитата(duk @  18.9.2008,  22:25 Найти цитируемый пост)
Там еще set есть.

По моему это не массив/список (что мне и надо) а множество и 
"sets contain no pair of elements e1 and e2 such that e1.equals(e2)" мне не подходит.


Цитата(polosatij @  18.9.2008,  22:43 Найти цитируемый пост)
ты очень сложно решение задачи написал.. я бы на твоём месте, сначало всё упростил..

Куда уж проще. Надо сделать класс "матрица" и реализовать умножение.

Цитата(polosatij @  18.9.2008,  22:43 Найти цитируемый пост)
ArrayList<Integer>.indexOf('Object') даст index

Индекс то мне зачем, известен уже.

А насчет ArrayList<Integer>.set(...) спасибо - попробую.

Автор: duk 19.9.2008, 19:26
Цитата(kosmonaFFFt @  19.9.2008,  09:53 Найти цитируемый пост)
Цитата(duk @  18.9.2008,  22:25 Найти цитируемый пост)
Там еще set есть.

По моему это не массив/список (что мне и надо) а множество и 
"sets contain no pair of elements e1 and e2 such that e1.equals(e2)" мне не подходит.


Я имел ввиду метод ArrayList<T>.set(int, T). Ты же писал, что не можешь изменить массив. Так вот тебе нужно исползовать set(int, T), так как начиная с java 5.0 при использовании интерфейсных типов (int, double ...) происходит автоупаковка/автораспаковка: int -> Integer(), Integer -> int. Так вот ты как раз и получаешь значение, а не ссылку (как бы работаешь с примитивом).

Автор: Platon 19.9.2008, 20:22
Уважаемый, а к чему такая сложная схема??? Java предоставляет богатый ассортимент инструментов не для того чтобы усложнять себе жизнь.
Почему бы вам не сделать такое:

http://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D1%82%D1%80%D0%B8%D1%86%D0%B0_(%D0%BC%D0%B0%D1%82%D0%B5%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0)

Код

import java.util.Arrays;

/**
 * Пользователь: Platon
 * Дата: 18.09.2008
 * Время: 22:23:37
 */
public class IntegerMatrix {

    private int[][] matrix;

    public IntegerMatrix(int rows, int cols) {
        this(new int[rows][cols]);
    }

    public IntegerMatrix(int[][] matrix) {
        this.matrix = matrix;
    }

    public int[][] getData() {
        return matrix;
    }

    public IntegerMatrix multiply(IntegerMatrix matrix) {
        int[][] m2 = matrix.matrix;
        int[][] m1 = this.matrix;
        if (m2.length != m1[0].length || m1.length != m2[0].length) throw new IllegalArgumentException("number of columns of the left matrix is not the same as the number of rows of the right matrix");
        int[][] res = new int[m1.length][m2[0].length];
        for (int i = 0; i < m1.length; i++)
            for (int j = 0; j < m2[0].length; j++) {
                int val = 0;
                for (int k = 0; k < m1[0].length; k++)
                    val += m1[i][k]*m2[k][j];
                res[i][j] = val;
            }
        return new IntegerMatrix(res);
    }

    public static void main(String[] args) {
        System.out.println(Arrays.deepToString(new IntegerMatrix(new int[][] {{2,3}, {5,7}}).multiply(new IntegerMatrix(new int[][] {{-1, 2}, {-2, 3}})).getData()));
        System.out.println(Arrays.deepToString(new IntegerMatrix(new int[][] {{-1, 2}, {-2, 3}}).multiply(new IntegerMatrix(new int[][] {{2,3}, {5,7}})).getData()));
    }
}

Автор: Shaggie 19.9.2008, 20:27
Ещё можно заглянуть во внутренности библиотеки http://commons.apache.org/math/, там есть классы для работы с матрицами. Возможно, опенсурсное решение придётся вам по вкусу  smile 

Автор: kosmonaFFFt 20.9.2008, 04:30
Цитата(duk @  19.9.2008,  19:26 Найти цитируемый пост)
Я имел ввиду метод ArrayList<T>.set(int, T). Ты же писал, что не можешь изменить массив. Так вот тебе нужно исползовать set(int, T), так как начиная с java 5.0 при использовании интерфейсных типов (int, double ...) происходит автоупаковка/автораспаковка: int -> Integer(), Integer -> int. Так вот ты как раз и получаешь значение, а не ссылку (как бы работаешь с примитивом).

Недопонял малость. smile

Сделал все с set, работает. Всем спасибо за помощь.

Автор: polosatij 20.9.2008, 10:31
если честно, я не понимаю, как люди могут писать такое

Код

                for (int k = 0; k < m1[0].length; k++)
                    val += m1[i][k]*m2[k][j];
                res[i][j] = val;[/quote]



 smile 

без скобок {}.. это чтоб себе и другим жизнь упростить типа?  smile 

Автор: Platon 20.9.2008, 10:48
Цитата(polosatij @  20.9.2008,  11:31 Найти цитируемый пост)
если честно, я не понимаю, как люди могут писать такое


А какие проблемы? Читается нормально...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)