Технический форум
Вернуться   Технический форум > Программирование > Форум программистов > Delphi, Kylix and Pascal


Ответ
 
Опции темы Опции просмотра
Старый 28.11.2010, 03:14   #1 (permalink)
Svetlanka
Member
 
Регистрация: 15.11.2010
Сообщений: 34
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
По умолчанию Перемножение матриц

Разработать программу перемножения двух матриц A и B размерности n*n. Обе матрицы размещаются в оперативной памяти динамически, а значение n вводится по запросу с клавиатуры.
Svetlanka вне форума   Ответить с цитированием

Старый 28.11.2010, 03:14
Helpmaster
Member
 
Аватар для Helpmaster
 
Регистрация: 08.03.2016
Сообщений: 0

В похожих обсуждениях вы наверняка найдете полезные ответы

Матрица. Как записать матрицу, составленную из трёх единичных матриц?
Обработка матриц. Паскаль
Обработка матриц

Старый 28.11.2010, 11:41   #2 (permalink)
Vladimir_S
Специалист
 
Регистрация: 27.08.2008
Адрес: Санкт-Петербург
Сообщений: 27,807
Сказал(а) спасибо: 340
Поблагодарили 583 раз(а) в 208 сообщениях
Репутация: 113184
По умолчанию

Цитата:
Сообщение от Svetlanka Посмотреть сообщение
Разработать программу перемножения двух матриц A и B размерности n*n. Обе матрицы размещаются в оперативной памяти динамически, а значение n вводится по запросу с клавиатуры.
Н-да... Вообще-то я сам не использую динамические массивы, а тут решил было разобраться, и, как выяснилось, впоролся в проблему, с которой сталкиваются все новички, пытающиеся работать с многомерными динамическими массивами. Суть вопроса такова. Если написать что-нибудь вроде
Код:
{$r-}
TYPE
 T=ARRAY[1..1,1..1] of Integer;
VAR
 A:^T;
 i,j,k,N:Integer;
BEGIN
 N:=2;
 GetMem(A, SizeOf(Integer)*N*N);

 WriteLn('Matrix A:');
 A^[1,1]:=1;
 A^[1,2]:=2;
 A^[2,1]:=3;
 A^[2,2]:=4;
 For i:=1 to N do
  begin
   For j:=1 to N do
    begin
     Write(A^[i,j]:4);
    end;
   WriteLn;
  end;
 
 FreeMem(A, SizeOf(Integer)*N*N);

 ReadLn;
END.
то выясняется, что транслятор не делает разницы между A^[i,j] и A^[j,i], т.е. переменной A^[1,2] присваивается значение 3. Полазал по Сети, убедился, что на этом подрывается куча народу, а вот внятных советов (кроме как перейти на статические массивы) не обнаружил. А теперь самому интересно стало.
Ау, есть спецы по динамическим массивам в Паскале? В чем ошибка и как правильно?
Vladimir_S вне форума   Ответить с цитированием
Старый 28.11.2010, 14:26   #3 (permalink)
Vladimir_S
Специалист
 
Регистрация: 27.08.2008
Адрес: Санкт-Петербург
Сообщений: 27,807
Сказал(а) спасибо: 340
Поблагодарили 583 раз(а) в 208 сообщениях
Репутация: 113184
По умолчанию

Цитата:
Сообщение от Vladimir_S Посмотреть сообщение
выясняется, что транслятор не делает разницы между A^[i,j] и A^[j,i], т.е. переменной A^[1,2] присваивается значение 3. Полазал по Сети, убедился, что на этом подрывается куча народу, а вот внятных советов (кроме как перейти на статические массивы) не обнаружил. А теперь самому интересно стало. Ау, есть спецы по динамическим массивам в Паскале? В чем ошибка и как правильно?
Отбой, похоже, сам разобрался. Ошибка возникает вследствие того, что адрес компоненты двумерного массива определяется, как произведение индексов, умноженное на количество бит, отводимых под переменную заявленного типа. Отсюда понятно, что перемена индексов местами адреса не меняет. Следовательно, похоже, ничего другого не остается, как преобразовать двумерный массив в одномерный. Тогда решение задачи о перемножении матриц получается таким:
Код:
{$r-}
TYPE
 T=ARRAY[1..1] of Integer;
VAR
 A,B,C:^T;
 i,j,k,N:Integer;
BEGIN
 Write('N= ');
 ReadLn(N);
 GetMem(A, SizeOf(Integer)*N*N);
 GetMem(B, SizeOf(Integer)*N*N);
 GetMem(C, SizeOf(Integer)*N*N);

 WriteLn('Matrix A:');
 For i:=1 to N do
  begin
   For j:=1 to N do
    begin
     A^[N*(i-1)+j]:=Random(20)-10;
     Write(A^[N*(i-1)+j]:4);
    end;
   WriteLn;
  end;
 WriteLn;

 WriteLn('Matrix B:');
 For i:=1 to N do
  begin
   For j:=1 to N do
    begin
     B^[N*(i-1)+j]:=Random(20)-10;
     Write(B^[N*(i-1)+j]:4);
    end;
   WriteLn;
  end;
 WriteLn;

 WriteLn('Matrix C:');
 For i:=1 to N do
  begin
   For j:=1 to N do
    begin
     C^[N*(i-1)+j]:=0;
     For k:=1 to N do
      C^[N*(i-1)+j]:=C^[N*(i-1)+j]+A^[N*(i-1)+k]*B^[N*(k-1)+j];
     Write(C^[N*(i-1)+j]:4);
    end;
   WriteLn;
  end;

 FreeMem(A, SizeOf(Integer)*N*N);
 FreeMem(B, SizeOf(Integer)*N*N);
 FreeMem(C, SizeOf(Integer)*N*N);

 ReadLn;
END.
По-моему, ужасно неудобно и некрасиво. Но что поделаешь...
Vladimir_S вне форума   Ответить с цитированием
Ads

Яндекс

Member
 
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Выкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.




Часовой пояс GMT +4, время: 22:51.

Powered by vBulletin® Version 6.2.5.
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.