Матричные вычисления C ++ - PullRequest
       3

Матричные вычисления C ++

2 голосов
/ 28 февраля 2011

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

EDITED --->>> Проблема, которая остается:

  • Он не распознает переменные "mat" в моих функциях.

error: 'mat' не был объявлен в этомсфера

 #include <iostream>
 #include <cstdio>
 #include <cstdlib> 
 #include <cmath>

using namespace std;

class matrix {
private:
int rows,columns;

public:
//constructor
matrix ()
{}
matrix(int _rows,int _columns) : rows(_rows),columns(_columns){
{
 int **mat=new int *[rows];
    for (int r = 0; r < rows; ++r)
        mat[r] = new int[columns];
}

}
//destructor
~matrix(){
for (int r = 0; r < rows; ++r)
        delete[] mat[r];
    delete[] mat;

}

//void allocate();
void getdata() {

cout <<"Enter number of rows :"<<endl;
cin >>rows;
cout <<"Enter number of columns : "<<endl;
cin >> columns;

}
void fill();
double determinant();
void showdata(){

}

};



int main()
{
matrix a;

a.getdata();
a.fill();
a.determinant();

    return 0;
}



//fills the matrix
void matrix ::fill(){

    for(int i=0;i<rows;i++) {
        for(int j=0;j<columns;j++){
        cout <<"Enter the elements in a line separated by whitespace :"<<endl;
        cin >>mat[i][j];
        }
    }

}
//calculate the determinant
double matrix :: determinant (){
    double det;
    det = mat[rows][columns]*mat[rows+1][columns+1] - mat[rows][columns+1]*mat[rows+1][columns];
    cout <<"The determinant of matrix is :"<<det<<endl;}

Ответы [ 5 ]

0 голосов
/ 28 февраля 2011

С вашим непосредственным вопросом:

mat представляется локальной переменной в вашем конструкторе, а не членом класса i и j - локальные переменные, объявленные в fill(), но не determinant()

Есть и другие важные проблемы:

  • Ваша матрица не инициализируется rows или columns. Они будут иметь любое случайное значение, и, учитывая, что они являются целыми числами со знаком, могут даже быть отрицательными. Ваш конструктор вполне может выбросить bad_alloc

  • заполнить чем?

  • Это неправильная формула для получения определителя, которая в любом случае применима только к квадратным матрицам

  • Было бы лучше использовать вектор, а не массивы и только один вектор. Посмотрите C ++ FAQ , чтобы увидеть самый простой способ сделать матрицу.

    Предполагая, что вы хотите, чтобы это была матрица типа int, а не double, объявите "mat" следующим образом:

    std::vector<int> mat;

Ваш конструктор должен выглядеть примерно так:

matrix::matrix (int r,int c) :
   rows(r), columns(c), mat(r*c)
{
    //body
}

Оператор перегрузки [], таким образом:

int* operator[](int r)
{
    return &mat[r*columns];
}

const int* operator[](int r) const
{
    return &mat[r*columns];
}

Обратите внимание, у нас есть 2 из них. Возможно реализовать одно с точки зрения другого. Некоторым также нравится перегружать operator (), чтобы получить 2 параметра, строку и столбец, но вышеприведенное сработает.

Вы можете предпочесть использовать size_t вместо int для измерений.

0 голосов
/ 28 февраля 2011

Инициализация mat принадлежит конструктору, скажем

matrix::matrix(int _rows, int _columns)
: rows(_rows)
, columns(_columns)
, mat(new int *[rows])
{
    for (int r = 0; r < rows; ++r)
        mat[r] = new int[columns];
}

Не забывайте деструктор:

matrix::~matrix()
{
    for (int r = 0; r < rows; ++r)
        delete[] mat[r];
    delete[] mat;
}

При этом я настоятельно рекомендую не изобретать еще одну."моя большая собственная матричная библиотека классов".Используйте что-нибудь эффективное и надежное, например, Eigen .

Кроме того, для контейнеров, если у вас нет действительно веских причин, используйте для этого хорошую библиотеку классов.Например, стандартная библиотека с std::vector и так далее, или (даже лучше на мой вкус): классы Qt, такие как QVector.

0 голосов
/ 28 февраля 2011

new оператор динамически выделяет память (т. Е. Из свободного хранилища).Таким образом, она должна быть частью любой функции-члена, чтобы назначить свой адрес возврата переменной-члену в этом примере, а не часть объявления класса.Он может быть частью вашей getdata() функции-члена.

А также, класс требует деструктор , потому что он управляет ресурсами.

Проблемы -

  1. int **mat=new int *[rows];, является локальной переменной в параметризованном конструкторе и выходит из области видимости после завершения вызова конструктора, поднимающего памятьутечки.

  2. С оператором matrix a; будет вызван конструктор по умолчанию.т.е. matrix::matrix(), конструктор без аргументов.Однако вы выполняете инициализацию в параметризованном конструкторе.

Чтобы все заработало, попробуйте это -

class matrix
{
    int **mat;
    // ...

    public:
    matrix()
    {
        cout <<"Enter number of rows :"<<endl;
        cin >>rows;
        cout <<"Enter number of columns : "<<endl;
        cin >> columns;

        mat=new int *[rows];
        for (int i=0;i<rows;i++) {
            mat[i]=new int [columns];
        }
    }

    // And no more, getdata() member function is required. Avoid it's call in main()
};

Надеюсь, это поможет!

0 голосов
/ 28 февраля 2011

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

EDIT : C ++ не позволяет инициализировать переменные-члены в куче при их объявлении. И в вашем случае размер матрицы неизвестен в первую очередь для mat, который будет создан с правильным объемом памяти. Как уже упоминалось здесь, используйте конструктор для создания экземпляра mat.

0 голосов
/ 28 февраля 2011

То, что вы пытаетесь сделать, это инициализировать mat массивом динамического размера. Это не может быть сделано, как говорит ваш компилятор, в константном выражении.

Вы должны написать конструктор для класса matrix, который будет принимать rows в качестве параметра и содержать строку mat=new int *[rows]. Обратите внимание, что вам также нужно инициализировать каждую строку mat; Ваш allocate метод делает это и должен вызываться из конструктора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...