PDA

Просмотр полной версии : Перемножение матриц...


VERte][
05.11.2007, 18:02
Пока разбирался с указателями с посыла inv, написал вот такую весчь, может кому пригодится:

#include<iostream>
using namespace std;

typedef int* pint;
void fillarray(pint array[], int m, int n);
void result(pint a[], pint b[], int m, int k ,int n);

int main()
{
int m,n,k;
char exit;
cout<<"Input 1st array size: "<<endl<<"m: ";
cin>>m; cout<<"n: "; cin>>k;
cout<<"Input 2nd array size: "<<endl<<"m: "<<k<<endl<<"n: ";
cin>>n;

pint *p=new pint[m],*q=new pint[k];
for (int i=0;i<m;i++)
p[i]=new int[k];

for (int i=0;i<k;i++)
q[i]=new int[n];

fillarray(p, m,k);
fillarray(q, k,n);

result(p,q,m,k,n);

for (int i=0;i<k;i++)
delete p[i];

for (int i=0;i<n;i++)
delete q[i];

delete[] p, q;

cout<<"Input any key to quit: ";
cin>>exit;
return 0;
}


void fillarray(pint array[], int m, int n)
{
cout<<"Input "<<m<<"x"<<n<<" array: "<<endl;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
cin>>array[i][j];
}

void result(pint a[], pint b[], int m, int k, int n)
{
int sum(0);
cout<<"Result "<<m<<"x"<<n<<" array:"<<endl;

for(int i=0; i<m; i++)
for(int j=0; j<n; j++)
{
for(int h=0; h<k ;h++)
{
sum=sum+a[i][h]*b[h][j];
}
cout<<sum<<" ";
sum=0;
if (j==n-1) cout<<endl;

}
}

прога перемножает 2 матрицы произволных размеров и выводит результат на экран (в отдельный массив забивать результат не стал ибо память и лень :) )

vp$
05.11.2007, 18:33
зачем изобретать велосипед, насколько я помню , в экселе это стандартная функция))

__mad
05.11.2007, 18:44
так он же вроде ясно написал "Пока разбирался с указателям..."
в экселе это будет посложней:d (разбираться с указателями)

nerezus
05.11.2007, 18:58
Ну блин, давайте теперь все свои лабы вываливать...

inv
05.11.2007, 19:00
Сделайте раздел для подобных случаев...че париться-то

~Lexx~
05.11.2007, 20:35
(в отдельный массив забивать результат не стал ибо память и лень :) )

Во первых - резон от такой проги, которая только выводит на экран рассчеты. Во вторых Это голый метод - никакой оптимизации. Это может написать каждый - пользы от него никакой.

Ладно сегодня завтра напишу немного по теории численных методов - чтобы не писали в лоб, а хотя бы немного оптимизировали.

VERte][
05.11.2007, 20:40
Давай, буду признателен

Sn@k3
05.11.2007, 21:11
есть такая софтина как mathlab(вроде), она считает енто

VERte][
05.11.2007, 21:23
я ж написал, что делал это с целью освоения указателей, не более, вдруг тоже кто-то будет с этим разбираться, а у меня как раз рассмотрены случаи динамических массивов и указатели, как параметры ф-ции...

~Lexx~
05.11.2007, 21:48
есть такая софтина как mathlab(вроде), она считает енто

Ну простите если матлаб это софтина))) матлаб это среда математического моделирования - очень мощная, и гибкая. Но Весит гиг (новая версия) и в нее еще надо врубиться. А перемножать матрицы проще конечно в экселе), да вот только куда приятнее самому написать метод, только толковый.

Forcer
06.11.2007, 00:24
Мне кажется, лучше подредактировать тему, закрепить и выкладывать в ней сорцы реализаций стандартных структур данных(либо ссылки на сорцы). Просто такого вроде бы нету на ачате, а например тоже самое перемножение матриц отлично бы смотрелось как перегрузка оператора * в специальном классе матрицы.

Серенький
06.11.2007, 00:39
нее еще надо врубиться
Для того, чтобы в матлабе перемножить две матрицы, особо и врубаться не нужно. А хелп все остальные вопросы лечит.

VERte][
06.11.2007, 19:04
вот небольшая поправка: запись результата в отдельный двумерный массив и последующий вывод результатов из него

#include<iostream>
using namespace std;

typedef int* pint;
void fillarray(pint array[], int m, int n);
pint* result(pint a[], pint b[], int m, int k ,int n);
void output(pint array[], int m, int n);

int main()
{
int m,n,k;
char exit;
cout<<"Input 1st array size: "<<endl<<"m: ";
cin>>m; cout<<"n: "; cin>>k;
cout<<"Input 2nd array size: "<<endl<<"m: "<<k<<endl<<"n: ";
cin>>n;

pint *p=new pint[m],*q=new pint[k], *res;

fillarray(p, m,k);
fillarray(q, k,n);
res=result(p,q,m,k,n);
output(res,m,n);


cout<<"Input any key to quit: ";
cin>>exit;
return 0;
}


void fillarray(pint array[], int m, int n)
{
for (int i=0;i<m;i++)
array[i]=new int[n];

cout<<"Input "<<m<<"x"<<n<<" array: "<<endl;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
cin>>array[i][j];
}

pint* result(pint a[], pint b[], int m, int k, int n)
{
int sum(0);
pint *temp = new pint[m];
for (int i=0;i<m;i++)
temp[i]=new int[n];

for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
temp[i][j]=0;



for(int i=0; i<m; i++)
for(int j=0; j<n; j++)
{
sum=0;
for(int h=0; h<k ;h++)
{
sum=sum+a[i][h]*b[h][j];
}
temp[i][j]=sum;
}
return temp;

for (int i=0;i<k;i++)
delete a[i];

for (int i=0;i<n;i++)
delete b[i];

delete[] a, b;
}

void output(pint array[], int m, int n)
{
cout<<"Result "<<m<<"x"<<n<<" array:"<<endl;
for (int i=0;i<m;i++)
for (int j=0;j<n;j++)
{
cout<<array[i][j]<<" ";
if (j==n-1) cout<<endl;
}
for (int i=0;i<n;i++)
delete array[i];
delete[] array;
}

Forcer
06.11.2007, 20:58
Уже не первый раз вижу подобное, поэтому решил написать.
Код:

for(int i=0; i<m; i++)
for(int j=0; j<n; j++)
{
sum=0;
for(int h=0; h<k ;h++)
{
sum=sum+a[i][h]*b[h][j];
}
temp[i][j]=sum;
}

Зачем объявлять доп. переменную sum? Не проще ли сделать так:

for(int i=0; i<m; i++)
for(int j=0; j<n; j++)
{
temp[i][j] = a[i][0]*b[0][j];
for(int h=1; h<k ;h++)
{
temp[i][j] += a[i][h]*b[h][j];
}
}


И еще по тексту: понимаю что прога маленькая и простенькая, но тем не менее - комментарий вообще нету, обработка исключительных ситуаций тоже отсутствует. Зачем в функции result после return какой-то текст? Он что, когда-то выполняться будет?Переменная exit тоже впринципе не нужна - символ можно поместить и в любую другую переменную, какая разница как он будет храниться? И еще: если хочешь разобраться с указателями, то я бы лично не использовал typedef и конструкции вида array[i][i] заменял бы на *(*(array+i)+j) и использовал бы по максимуму арифметику с указателями. Через некоторое время(впринципе непродолжительное :) ) приходит понимание и привыкаешь к указателям. Мое имхо :).

VERte][
07.11.2007, 01:49
справедливо, буду учится =) я ж ток начинаю

VERte][
07.11.2007, 23:54
Зачем объявлять доп. переменную sum? Не проще ли сделать так:

for(int i=0; i<m; i++)
for(int j=0; j<n; j++)
{
temp[i][j] = a[i][0]*b[0][j];
for(int h=1; h<k ;h++)
{
temp[i][j] += a[i][h]*b[h][j];
}
}



А вот ещё проще, зачем надо было ставить строчку temp[i][j] = a[i][0]*b[0][j]; ?
можно вот так:


for(int i=0; i<m; i++)
for(int j=0; j<n; j++)
for(int h=0; h<k ;h++)
temp[i][j] += a[i][h]*b[h][j];

Forcer
08.11.2007, 00:09
Vertexe
По адресу temp[i][j] изначально находтися неинициализированное значение. Т.е. совершенно случайное число. Дальше по коду ты предлагаешь прибавлять к этому числу произведения соответствующих элементов. Это неправильно. Нам нужно чтобы там стоял 0, либо произведение первых двух элементов, как и было реализовано в моем сорце.

VERte][
08.11.2007, 00:12
заметь что в коде у меня идёт сначала обнуление массива temp!!!

Forcer
08.11.2007, 00:24
Признаюсь, не заметил. =) Но, мне кажется его лучше убрать. В нем нет необходимости. Когда обнуляешь - прогоняешь цикл лишний раз по всем элементам. Это не рационально. Получается огромная потеря по производительности. Раза в 2-а наверное.

VERte][
08.11.2007, 00:31
Тоже верно...

[Y.P.C.]yla
02.12.2007, 20:47
какая полезная тема!Про перемножение матриц это задание с моей контрольной....еслиб еще умножение матрицы на число, , умножение вектора на матрицу, получение обратной матрицы было...

Ch3ck
02.12.2007, 21:02
http://www.srcc.msu.su/num_anal/lib_na/cat/cat528.htm
Тут глянь

[Y.P.C.]yla
02.12.2007, 21:34
Дрочек пасиб за ссылку)) все..все есть))нашла))пасиб)))