Условие задачи приблизительно следующее (письменного варианта условия нет, поэтому пишу по памяти). Даны 2 матрицы размерами r на c и r1 на c1. Вычислить их произведение. Учесть условие допустимости.
Что нужно для вычисления?
Данная задача - чистой воды математика. Для ее решения нужны не сложные правила вычисения произведения двух матриц. Условие допустимости здесь подразумевает, что количество столбцов 1-й матрицы должно совпадать с количеством строк 2-й матрицы. Размерность результирующей матрицы будет m на n1. И, конечно же, потребуется общая формула.
Пусть C - результирующая матрица размерами m на n1; A, B - исходные матрицы; i = 1, 2, 3, ... , r; j = 1, 2, 3, ... , c1; x = 1, 2, 3, ... , c.
Здесь индексы i и j используются для прохождения по элементам результирующего массива и, соответственно, для прохождения по строкам первого массива и по столбцам второго. Индекс x используется для того, чтобы можно было обойти все столбцы первой и все строки второй матриц.
Расчитать все элементы результирующего массива помогут три вложенных цикла.
for (i=0; i<r; i++) { for (j=0; j<c1; j++) { C.getMatrix()[i][j] = 0; for (int x=0; x<c; x++) { C.getMatrix()[i][j] += A.getMatrix()[i][x]*B.getMatrix()[x][j]; } printf("%4d", C.getMatrix()[i][j]); } printf("\n"); }
Проверка условия допустимости осуществляется условным блоком if (c == r1) {...}.
Это, собственно, все, что касается вычислений.
Массив как объект.
Как Вы уже заметили в заголовке статьи упоминается класс Matrix, а в участке кода, приведенном выше используются объекты A, B, и C. Конечно, по правде говоря, инструменты для создания массива и прочие удобства являются "украшательством". Но нельзя не заметить, что в условии задачи не указана точная размерность матриц. Следовательно, в программе должно быть организовано создание массивов динамической размерности. В полне логично предположить, что писать код, создающий массив с заданными пользователем параметрами, для каждого из трех массивов очень не удобно и не рационально.
Вместо этого можно поступить следующим образом. Приведенный ниже класс весьма прост в использовании и экономит лишние пару десятков строк в листинге.
class Matrix { private: int rows,cols,**A; public: void setCols(int num) {cols = num;} // задать количество колонок void setRows(int num) {rows = num;} // задать количество строк int getCols(void) {return cols;} // получить количество колонок int getRows(void) {return rows;} // получить количество строк void setMatrix() // выделить память для массива { try { A = new int*[rows]; for (int i=0;i<rows;i++) A[i] = new int[cols]; } catch(int e) {A = 0;} } int **getMatrix() {return A;} // получить указатель на массив void Destroy(void) {delete(this);} // удалить объект (ОБЯЗАТЕЛЬНЫЙ МЕТОД!!!) };
Примечания: метод getMatrix() можно вызывать только поле вызова метода setMatrix(), а этот, в свою очередь, после вызовов setRows() и setCols(); метод Destroy() можно вызывать в любой момент после создания объекта (экземпляра класса), кроме того, лучше вызывать этот метод сразу же, как только объект более не нужен (это сэкономит оперативную память, особенно при работе сбольшими массивами).
Конечно же можно организовать создание массива динамической размерности с помощью обычной функции, но для этого в основной функции main() потребуется объявление дополнительных переменных, что не совсем удобно, особенно если массивов потребуется больше трех. Но это, опять же, дело вкуса.
Далее приведен полный пример кода программы с комментариями.
class Matrix { private: int rows,cols,**A; public: void setCols(int num) {cols = num;} // set number of columns void setRows(int num) {rows = num;} // set number of rows int getCols(void) {return cols;} // get number of columns int getRows(void) {return rows;} // get number of rows void setMatrix() // creat empty array { try { A = new int*[rows]; for (int i=0;i<rows;i++) A[i] = new int[cols]; } catch(int e) {A = 0;} } int **getMatrix() {return A;} // get empty array void Destroy(void) {delete(this);} // delet object };
void main() { int r,c,r1,c1, i, j; char cr[]={' '},cc[]={' '},cr1[]={' '},cc1[]={' '}; Matrix A,B,C; // creat objects randomize(); // get size of 1st matrix printf("Enter size of 1st matrix (Not leters! Not 0!)\n"); do { printf("Rows: "); gets(cr); r = atoi(cr); } while (!r); do { printf("Columns: "); gets(cc); c = atoi(cc); } while (!c); // get size of 2nd matrix printf("Enter size of 2nd matrix (Not leters! Not 0!)\n"); do { printf("Rows: "); gets(cr1); r1 = atoi(cr1); } while (!r1); do { printf("Columns: "); gets(cc1); c1 = atoi(cc1); } while (!c1); // creat arrays A.setRows(r); A.setCols(c); A.setMatrix(); B.setRows(r1); B.setCols(c1); B.setMatrix(); C.setRows(r); C.setCols(c1); C.setMatrix(); // add random numbers in 1st matrix and write it printf("\n1st matrix:\n"); for (i=0; i<r; i++) { for (j=0; j<c; j++) { A.getMatrix()[i][j] = random(10); printf("%d ", A.getMatrix()[i][j]); } printf("\n"); } // add random numbers in 2nd matrix and write it printf("\n2nd matrix:\n"); for (i=0; i<r1; i++) { for (j=0; j<c1; j++) { B.getMatrix()[i][j] = random(10); printf("%d ", B.getMatrix()[i][j]); } printf("\n"); } // can be calculatade? if (c == r1) { // calculate C=A*B and write C printf("\nResult matrix:\n"); for (i=0; i<r; i++) { for (j=0; j<c1; j++) { C.getMatrix()[i][j] = 0; for (int x=0; x<c; x++) { C.getMatrix()[i][j] += A.getMatrix()[i][x]*B.getMatrix()[x][j]; } printf("%4d", C.getMatrix()[i][j]); } printf("\n"); } } else printf("\nNumber of 1st matrix's colums and number of 2nd matrix's rows is NOT SAME!"); getch(); A.Destroy(); B.Destroy(); C.Destroy(); }
Проверка на число.
К слову о приеме данных от пользователя. В данной программе в качестве данных требуются только числа. Но тем не менее введенная пользователем строка записывается в символьную переменную, а затем эта строка преобразовывается в целое число. Вся суть этих наворотов в том, что если будет введено что-то кроме цифр, то это "что-то" не преобразуется в число. Именно на этом основана проверка на число введенных данных. Метод верный, но при его использовании обнаруживается небольшой недостаток. Если даже ввести два числа через пробел, воспринимается только первое из них. То, которое стоит после пробела игнорируется. Вероятно, это связано с особенностями работы функции преобразования строки в целое число atoi().
P.S. Если у кого есть другие идеи организации проверки введенных данных на число, жду комментариев.