Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Шабл.класс "Матрица".Помогите сделать пожалуйста! 
V
    Опции темы
yorgan
  Дата 5.6.2008, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Всем привет.
Есть такое задание:
Нужно написать шаблонный класс "матрица", в котором будет:
1. конструктор (матрица размером 10 на 20).
2. деструктор.
3. нахождение детерминанта матрицы (определителя).
4. нахождение обратной матрицы.
5. Вывод элемента [][];
6. Умножение матрицы А на B.

У меня такие вопросы:
Как выделять в конструкторе память динимически под матрицу заданной размерности (соответственно как освобождать помять в деструкторе)?
Как находить определитель матрицы (на сколько я понимаю это будет рекурсивная функция)? Если была бы матрица 3 на 3, я нашел бы без проблем, а вот 10 н 20... не знаю :(
Вывод элемента... вот тут я не очень понял. Если просто написать функцию-член, которая будет по заданным [i][j] выводить на экран элемент, то это просто, а если нужо переопределить операцию [][]...???

Помогите пожалуйста.
PM MAIL   Вверх
dragomir
Дата 5.6.2008, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 28.1.2007
Где: Брянск

Репутация: нет
Всего: нет



Цитата(yorgan @  5.6.2008,  16:56 Найти цитируемый пост)
Как находить определитель матрицы (на сколько я понимаю это будет рекурсивная функция)? Если была бы матрица 3 на 3, я нашел бы без проблем, а вот 10 н 20... не знаю :(


Вроде бы методом Гаусса можно найти определитель любой матрицы
PM MAIL   Вверх
yorgan
Дата 5.6.2008, 17:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



На сколько я помню курс линейной алгебры... методом Гаусса ищется корни СЛАУ (систем линейных алгебраических уравнений)
PM MAIL   Вверх
bronislav
Дата 5.6.2008, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



Цитата(yorgan @  5.6.2008,  15:56 Найти цитируемый пост)
Как находить определитель матрицы (на сколько я понимаю это будет рекурсивная функция)? Если была бы матрица 3 на 3, я нашел бы без проблем, а вот 10 н 20... не знаю :(

Насколько я знаю можно найти (без до определения) только определитель квадратной матрицы.
Посмотри тут.

Добавлено через 35 секунд
Цитата(yorgan @  5.6.2008,  16:39 Найти цитируемый пост)
методом Гаусса ищется корни СЛАУ (систем линейных алгебраических уравнений) 

Именно так

Добавлено через 4 минуты и 2 секунды
и тут


--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
IKM2007
Дата 5.6.2008, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Зима близко
**


Профиль
Группа: Участник
Сообщений: 702
Регистрация: 26.4.2008
Где: olmedreca

Репутация: 3
Всего: 40



Цитата(yorgan @  5.6.2008,  16:56 Найти цитируемый пост)
Как выделять в конструкторе память динимически под матрицу заданной размерности (соответственно как освобождать помять в деструкторе)?

Код

#include <assert.h>
class Matrix
{
public:
Matrix(int=10,int=20);//default constructor
~Matrix();
private:
int    **a;
int n;
int m;
};
Matrix::Matrix(int x,int y)//constructor
{
    n=x;
    m=y;
a=new int *[n];
assert(a);
for(int i=0;i<n;i++)
{a[i]=new int [m];
assert(a[i]);
}

for(i=0;i<n;i++)
for(int j=0;j<m;j++)
a[i][j]=0;
}
Matrix::~Matrix()//destructor
{
for(int i=0;i<n;i++)
delete [] a[i];
delete [] a;
}

На остальное нет ни идей,ни времени(Завтра экзамен).


--------------------
"К чёрту обстоятельства, я создаю возможности."
Брюс Ли
PM MAIL Skype   Вверх
bronislav
Дата 5.6.2008, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



Цитата(yorgan @  5.6.2008,  15:56 Найти цитируемый пост)
конструктор (матрица размером 10 на 20).

Я бы рекомендовал размер матрицы задавать в параметрах конструктора. А их можно сделать со значениями по умолчанию, если тебе так нужен размер 10 x 20.


--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
bronislav
Дата 5.6.2008, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



IKM2007,
Цитата(yorgan @  5.6.2008,  15:56 Найти цитируемый пост)
Нужно написать шаблонный класс "матрица", в котором будет:


Ключевое слово тут шаблонный.

Например вот так:

Код

#ifndef MATRIX_H_
#define MATRIX_H_

#include <iostream>
#include <exception>

template < class T >
class matrix
{
private:
    T** data; // массив элементов матрицы
    int rows; // количество строк
    int cols; // количество столбцов
public:
    matrix( int _rows = 10, int _cols = 20 );
    ~matrix( );
    
    
};

template < class T >
matrix< T >::matrix( int _rows, int _cols )
: rows( _rows ), cols( _cols )
{
    try
    {
        data = new T* [ rows ];
        for( int i = 0; i < rows; i++ )
            data[ i ] = new T [ cols ];
    }
    catch( std::exception e )
    {
        std::cerr << "matrix::matrix(" << _rows << ", " << _cols << "): " << e.what() << std::endl;
    }
}

template < class T >
matrix< T >::~matrix()
{
    try
    {
        for( int i = 0; i < rows; i++ )
        {
            if( data[ i ] != NULL )
                delete [] data[ i ];
            else
                break;
        }
        if( data != NULL )
            delete [] data;
    }
    catch( std::exception e )
    {
        std::cerr << "matrix::~matrix( ): " << e.what() << std::endl;
    }
}

#endif /*MATRIX_H_*/


А использовать так:
Код

#include "matrix.h"

int main()
{
    matrix< int >(5,6);
    return 0;
}




--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
Dmi3ev
Дата 5.6.2008, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

Репутация: 13
Всего: 41



Код

float **matrix;
matrix = new *[n];
for (int j=0; j<m; j++)
 matrix[j]=new float[n];

можно так создавать матрицу динамически, как вариант. а вообще не понятно зачем это делать, если размерность заранее известна?

Добавлено через 1 минуту и 51 секунду
а вот так если:
Код

class Matrix
{
public:
 Matrix (){};
 void Set(float a11, float a12, float a13, float a21, float a22, float a23, float a31, float a32, float a33)
  {
   m[0][0]=a11;
   m[0][1]=a12;
   m[0][2]=a13;
   m[1][0]=a21;
   m[1][1]=a22;
   m[1][2]=a23;
   m[2][0]=a31;
   m[2][1]=a32;
   m[2][2]=a33;
  };
 float Determ()
  {
   float det=(m[0][0]*m[1][1]*m[2][2])+(m[0][1]*m[1][2]*m[2][0])+
             (m[2][0]*m[0][2]*m[2][1])-(m[0][1]*m[1][0]*m[2][2])-
             (m[0][0]*m[1][2]*m[2][1])-(m[0][2]*m[1][1]*m[2][0]);
   return det;
  };

 ~Matrix(){};
private:
 float m[3][3];
};



--------------------

PM MAIL   Вверх
bronislav
Дата 5.6.2008, 18:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



Цитата(Dmi3ev @  5.6.2008,  17:06 Найти цитируемый пост)
если размерность заранее известна?

А что если размерность заранее известна, то ее лучше в стеке создать? А если экземпляров класса будет 100-200.
ИМХО такой подход не есть гуд. 


--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
yorgan
Дата 5.6.2008, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Пока писал, уже несколько людей ответили. Сейчас буду разбираться. Всем большое спасибо за желание помочь!!!  smile 

Цитата(bronislav @  5.6.2008,  17:40 Найти цитируемый пост)
Насколько я знаю можно найти (без до определения) только определитель квадратной матрицы.
Посмотри тут.

Да, вы правы.  Сейчас еще посмотрел учебник по математике. Значит преподаватель ошибся.

IKM2007, спасибо. Уже что-то... а то голова гудит, не знаю даже с чего начать. 

Тогда вопрос таков: как найти детерминант квадратной матрицы 10 на 10? 
Мне бы посмотреть на код, где вычисляется хотя бы определитель матрицы 4 на 4 (как я понял есть только один метод нахождения определителя матрицы N-го порядка -  с помощью суммы произведений элементов некоторого ряда на соотвествующие им алгебраические дополнения).

Это сообщение отредактировал(а) yorgan - 5.6.2008, 18:14
PM MAIL   Вверх
Dmi3ev
Дата 5.6.2008, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

Репутация: 13
Всего: 41



ну если говорить о матрице 4*4, то тогда формула определителя такова:
det A=a11*(-1)^(1+1)*(det (та же матрица, только надо вычеркнуть строку и столбец где расположен a11))+
          a12*(-1)^(1+2)*(det (та же матрица, только надо вычеркнуть строку и столбец где расположен a12))+
           a13*(-1)^(1+3)*(det (та же матрица, только надо вычеркнуть строку и столбец где расположен a13))+
           a14*(-1)^(1+4)*(det (та же матрица, только надо вычеркнуть строку и столбец где расположен a12))
а как считать определитель для матрицы 3*3, которая получается в скобках я написал в описании класса Matrix (метод Determ), я считал по правилу Саррюса

Добавлено через 3 минуты и 44 секунды
Цитата

А что если размерность заранее известна, то ее лучше в стеке создать? А если экземпляров класса будет 100-200.
ИМХО такой подход не есть гуд. 

вообще да, но если 10 на 20 и в массиве хранятся числа, а не большие боъекты , то, мне кажется, по барабану


--------------------

PM MAIL   Вверх
bronislav
Дата 5.6.2008, 19:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



Цитата(Dmi3ev @  5.6.2008,  17:25 Найти цитируемый пост)
вообще да, но если 10 на 20 и в массиве хранятся числа, а не большие боъекты , то, мне кажется, по барабану 

Мне кажется, что даже для небольших матриц это не хорошая практика ибо привыкнешь  smile 


--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
yorgan
  Дата 5.6.2008, 21:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Функции нахождения детерминатна и обратной матрицы, ввода матриц и перемножения матриц:
Код

double determinant(int **a, int N) 

  int i,j; 
  int **matr1; 
  double determ=0; 

    matr1=new int*[N-1]; 
 
    for(i=0;i<N;i++) 
    { 
      for(j=0;j<N-1;j++) 
     { 
      if(j<i)   {matr1[j]=a[j];} 
      else      {matr1[j]=a[j+1];} 
      } 
      determ+=pow(-1,(i+j))*determinant(matr1,N-1)*a[i][N-1]; 
    } 
    delete matr1; 
  } 
 
  return determ; 
}

////////////

void show_obratnaya_matrica(int **a, int N)
{
    matr=new int*[N];
   double det = 0; 
   int i, j, k;
    for( i = 0; i < N; i++)
    {
        for( j = 0; j < N; j++)
        {
            matr[i*N + j] = a[j*N + i];
        }
    }
  det = determinant(a,N);

    for( i = 0; i < N; i++)
    {
        cout << "\n";
        for( j = 0; j < N; j++)
        {
            matr[i*N + j] = matr[j*N + i] * (1\det);
            cout  << matr[i*N + j];
        }
    }
 delete matr;
}
/////////////
void vvodmatrAandB(int **a, int **b, int  N)
{
   int i, j;
    for( i = 0; i < N; i++)
    {
        for( j = 0; j < N; j++)
        {
            cin >> a[i*N + j];
            cin >> b[i*N + j];
     
        }
    }
    
}

////////////
void peremnojehieAB(int **a, int **b, int **c, int  N))
{
     for(i=0;i<N;I++)   
    {
        for(j=0;j<N;j++) 
        {
         c[i*N + j]=0;
         for(k=0;k<N;k++) 
         {
              C[i*N + j]+=a(i*N + k)*b(k*N + j); 
          }
      }
  }
}



У меня еще пока плохо с ООП в целом и с шаблонами в частности, может кто-то может подсказать как притулить эту функцию как метода класса к коду bronislav'а:


Код

#ifndef MATRIX_H_
#define MATRIX_H_

#include <iostream>
#include <exception>

template < class T >
class matrix
{
private:
    T** data; // массив элементов матрицы
    int rows; // количество строк
    int cols; // количество столбцов
public:
    matrix( int _rows = 10, int _cols = 10 );
    ~matrix( );
    
    
};

template < class T >
matrix< T >::matrix( int _rows, int _cols )
: rows( _rows ), cols( _cols )
{
    try
    {
        data = new T* [ rows ];
        for( int i = 0; i < rows; i++ )
            data[ i ] = new T [ cols ];
    }
    catch( std::exception e )
    {
        std::cerr << "matrix::matrix(" << _rows << ", " << _cols << "): " << e.what() << std::endl;
    }
}

template < class T >
matrix< T >::~matrix()
{
    try
    {
        for( int i = 0; i < rows; i++ )
        {
            if( data[ i ] != NULL )
                delete [] data[ i ];
            else
                break;
        }
        if( data != NULL )
            delete [] data;
    }
    catch( std::exception e )
    {
        std::cerr << "matrix::~matrix( ): " << e.what() << std::endl;
    }
}

#endif /*MATRIX_H_*/


И если не сложно, то не могли бы объяснить что есть exception.h  и почему такой синтаксис в этой строке: : rows( _rows ), cols( _cols )?

Это сообщение отредактировал(а) yorgan - 5.6.2008, 23:39
PM MAIL   Вверх
bronislav
Дата 6.6.2008, 09:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



Цитата(yorgan @  5.6.2008,  20:47 Найти цитируемый пост)
И если не сложно, то не могли бы объяснить что есть exception.h  и почему такой синтаксис в этой строке: : rows( _rows ), cols( _cols )?

Это код проводит инициализацию членов данных класса параметрами конструктора.

Цитата(yorgan @  5.6.2008,  20:47 Найти цитируемый пост)
не могли бы объяснить что есть exception.h 

Во первых просто exception без h.
Это заголовочный файл про обработку исключений. Вопросы по обработке исключений уже много раз поднимались на форуме, воспользуйся поиском или посмотри вот в этой теме например.

Добавлено через 1 минуту и 40 секунд
Да и умножение и ввод матриц можно, даже скорее нужно реализовать через перегрузку операторов.


--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
yorgan
Дата 6.6.2008, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Вот что-то навоял. Посмотрите пожалуйста в чем ошибки?

Код

#ifndef MATRIX_H_
#define MATRIX_H_

#include <iostream>
#include <exception>
#define N 10

template < class T >
class matrix
{
private:
    T** a, b, c; // массив элементов матриц
    int rows; // количество строк
    int cols; // количество столбцов
public:
    matrix( int _rows = 10, int _cols = 10 );
    ~matrix( );
    void vvodmatrAandB(int, int, int)
    T determinant(int, int);
    void peremnojehieAB(int, int, int, int)
    
    
};

template < class T >
matrix< T >::matrix( int _rows, int _cols )
: rows( _rows ), cols( _cols )
{
    try
    {
        a = new T* [ rows ];
        for( int i = 0; i < rows; i++ )
            a[ i ] = new T [ cols ];
        b = new T* [ rows ];
        for( int i = 0; i < rows; i++ )
            b[ i ] = new T [ cols ];
        c = new T* [ rows ];
        for( int i = 0; i < rows; i++ )
            c[ i ] = new T [ cols ];
    }
    catch( std::exception e )
    {
        std::cerr << "matrix::matrix(" << _rows << ", " << _cols << "): " << e.what() << std::endl;
    }
}

template < class T >
matrix< T >::~matrix()
{
    try
    {
        for( int i = 0; i < rows; i++ )
        {
            if( a[ i ] != NULL )
                delete [] a[ i ];
            else
                break;
        }
        if( data != NULL )
            delete [] a;
        

        for( int i = 0; i < rows; i++ )
        {
            if( a[ i ] != NULL )
                delete [] b[ i ];
            else
                break;
        }
        if( data != NULL )
            delete [] b;

        for( int i = 0; i < rows; i++ )
        {
            if( a[ i ] != NULL )
                delete [] c[ i ];
            else
                break;
        }
        if( data != NULL )
            delete [] c;
    }
    catch( std::exception e )
    {
        std::cerr << "matrix::~matrix( ): " << e.what() << std::endl;
    }
}

template < class T >
void matrix< T >:: vvodmatrAandB(int **a, int **b, int  N)
{
   int i, j;
    for( i = 0; i < N; i++)
    {
        for( j = 0; j < N; j++)
        {
            cin >> a[i*N + j];
            cin >> b[i*N + j];
     
        }
    }
    
}


template < class T >
T matrix < T >:: determinant(int **a, int N)

  int i,j; 
  int **matr1; 
  double determ=0; 

    matr1=new int*[N-1]; 
 
    for(i=0;i<N;i++) 
    { 
      for(j=0;j<N-1;j++) 
     { 
      if(j<i)   {matr1[j]=a[j];} 
      else      {matr1[j]=a[j+1];} 
      } 
      determ+=pow(-1,(i+j))*determinant(matr1,N-1)*a[i][N-1]; 
    } 
    delete matr1; 
  } 
 
  return determ; 
}

template < class T >
void matrix< T >:: show_obratnaya_matrica(int **a, int N)
{
    matr=new int*[N];
   double det = 0; 
   int i, j, k;
    for( i = 0; i < N; i++)
    {
        for( j = 0; j < N; j++)
        {
            matr[i*N + j] = a[j*N + i];
        }
    }
  det = determinant(a,N);

    for( i = 0; i < N; i++)
    {
        cout << "\n";
        for( j = 0; j < N; j++)
        {
            matr[i*N + j] = matr[j*N + i] * (1\det);
            cout  << matr[i*N + j];
        }
    }
 delete matr;
}



#endif /*MATRIX_H_*/

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1540 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.