Суббота, 20.04.2024, 07:27 | RSS | Приветствую Вас Гость
Главная | Регистрация | Вход
Меню сайта
Категории раздела
Разное [10]
Решения задач (студентам) [9]
PC Игры - кодинг [2]
Python [1]
PHP, Mysql [1]
HTML, CSS, Javascript [1]
Scilab [1]
Поиск
Опрос
Какую социальную сеть Вы предпочитаете?
Всего ответов: 43
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Главная » Статьи » Решения задач (студентам)

Вычисление произведения 2-х матриц. Класс Matrix.
Условие задачи приблизительно следующее (письменного варианта условия нет, поэтому пишу по памяти).
Даны 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] = A[1][1] * B[1][1] + ... + A[i][x] * B[x][j]

Здесь индексы 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() потребуется объявление дополнительных переменных, что не совсем удобно, особенно если массивов потребуется больше трех. Но это, опять же, дело вкуса.

Далее приведен полный пример кода программы с комментариями.

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <alloc.h>

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. Если у кого есть другие идеи организации проверки введенных данных на число, жду комментариев.
Поделиться ссылкой в соц. сетях:

Категория: Решения задач (студентам) | Добавил: =Sanek= (09.09.2011)
Просмотров: 2646 | Комментарии: 4 | Теги: произведение матриц, MATRiX, Destroy, class, Класс, проверка на число, C/C++, atoi() | Рейтинг: 0.0/0
Всего комментариев: 4
3 DreD  
0
Ох епты! И это нам надо будет делать?

4 =Sanek=  
0
Наверняк biggrin Да и ладно, я ж все расписал буквально по строчкам.

1 cheper  
1
Спасибо за задачу и хорошее описание и комментарии в задачи все отлично работает. smile

2 =Sanek=  
0
На сколько я понял, идей по поводу проверки на число у тебя нет... а зря.

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

© 2024 raznocoding.do.am