Nevíte-li si rady s jakýmkoliv matematickým problémem, toto místo je pro vás jako dělané.
Nástěnka
❗22. 8. 2021 (L) Přecházíme zpět na doménu forum.matweb.cz!
❗04.11.2016 (Jel.) Čtete, prosím, před vložení dotazu, děkuji!
❗23.10.2013 (Jel.) Zkuste před zadáním dotazu použít některý z online-nástrojů, konzultovat použití můžete v sekci CAS.
Nejste přihlášen(a). Přihlásit
function maticove_nasobeni(matice1,matice2:matice):matice;
var i,j,k:integer;
begin
for i:=1 to n do begin
for j:=1 to n do begin
for k:=1 to n do begin
maticove_nasobeni[i][j]:=matice1[i][k]*matice2[k][j]+maticove_nasobeni[i][j];
end;
end;
end;
end;
Prosim, co je na tomto algoritmu maticvoeho nasobeni matic nxn spatne?
Offline
Zdravím,
a) Kód by měl být v tagách code.
b) Tak, jak to máš ty, tak se snažíš vracet typ: matice. Jak je definován tento typ? Měl by být nějak takto:
type matice = Array[1..MAX_I][1..MAX_J] of integer;
c) Co to píše za chybu?
d) Poznámka. Jinak se obávám, že to funguje jako v ostatních prog. jazycích. To znamená, že přímo matici nevrátíš, to je logické, ale můžeš vrátit ukazatel, který ukazuje právě na tuto matici. ;-)
Offline
1) OK.
2) Ano, tak to mám.
3) Chybu to nepíše, ten program se spustí, ale špatně to vypisuje znásobenou matici.
4) V této fázi jsme ještě s ukazateli nepracovali, takže by to mělo jít vypsat s použitím pár for cyklů po prvcích, jenže tam bude nejspíš chyba...
begin
for i:=1 to n do
begin
for j:=1 to n do
begin
for k:=1 to n do
begin
write (maticove_nasobeni(matice_A,matice_B)[i,j]);
end;
end;
writeln;
end;
readln;
end;Offline
Super odpověď, můžeme pokračovat.
V Pascalu jak již víme, máme dva druhy příkazů pro bloky:
procedure
- slouží pro výpis a nic nevrací, při použití pole můžeme pole ihned bez problémů vypsat
function
- vrací hodnotu, při použití pole musíme používat a vracet pointer (ukazatel)
Takže v našem případě (pokud ještě neprobíráte pointers) musíme použít tu první variantu (procedure). Program zkopilovat jde, což je v pořádku. Chybu musíme hledat v algoritmu (píšeš, že to vypisuje nesmyslné hodnoty). Jaký je tedy algoritmus pro násobení dvou matic? Součin dvou matic si můžeme představit (pseudojazykem - i když takto je to obdobně v Pascalu) takto:
VýslednáMatice[i, j] = SUMA(PrvniMatice[i, k] * DruháMatice[k, j]);
i: pomocná proměnná, která nabývá hodnot do M (M bude v parametru procedury)
j: pomocná proměnná, která nabývá hodnot do P (P bude v parametru procedury)
k: pomocná proměná, která nabývá hodnot do N (N bude v parametru procedury)
Co takto:
Procedure maticoveNasobeni(var matice1, matice2, vystup: matice; M, N, P: integer);
var i, j, k: integer;
begin
for i := 1 to M do
for j := 1 to P do
begin
vystup[i, j] := 0;
for k := 1 to N do vystup[i, j] := vystup[i, j] + matice1[i, k] * matice2[k, j];
write(vystup[i, j]);
end;
end;Samozřejmě matice výstupní (vystup) nemusí být přímo v parametru procedurky, může se vyskytovat až v daném tělu procedurky. Domnívám se, že chyba byla v přednostních operacích.
Offline
↑ RePRO:
Takze ted si akorat nahradil proceduru za funcki, ale jak tedy vypisu ta data?(matici)
Mam napsano
program Matrix_mult;
type matice=array[1..10,1..10] of integer;
var m,n,i,j,k:integer;
matice_A, matice_B:matice;
vysledna_matice:matice;
begin
Writeln('=====================================');
Writeln('Vitejte v programu NASOBENI MATIC');
Writeln('=====================================');
write('Zadejte pocet radku matice A: ');
readln(n);
write('Zadejte pocet sloupcu matice A: ');
readln(n);
for i:=1 to n do
for j:=1 to n do
begin
write('Vlozte clen na pozici [',i,',',j,']: ');
readln(matice_A[i,j]);
end;
Writeln('=====================================');
Writeln('Vami zadana matice A:');
for i:=1 to n do
begin
for j:=1 to n do
begin
write (matice_A[i,j]);
end;
writeln;
end;
readln;
Writeln('=====================================');
write('Zadejte pocet radku matice B: ');
readln(n);
write('Zadejte pocet sloupcu matice B: ');
readln(n);
for i:=1 to n do
for j:=1 to n do
begin
write('Vlozte clen na pozici [',i,',',j,']: ');
readln(matice_B[i,j]);
end;
Writeln('=====================================');
Writeln('Vami zadana matice B:');
for i:=1 to n do
begin
for j:=1 to n do
begin
write (matice_B[i,j]);
end;
writeln;
end;
readln;
Writeln('=====================================');a chci aplikovat tu tvoji proceduru na svoje dve matice tak, abych pak mohl vypsat vyslednou matici.
P.S. nektere variables jsou tam zbytecne, je to priprava k tomu abych mohl udelat mxn maticovy soucin
Offline
Teď jsem to zkoušel prohnat kompilátorem a jde to, lépe to asi sesmolit nejde. Funkce by na to byly určitě lepší, ale to bychom museli použít ty pointery. Konstanty (N, L, M) samozřejmě měnit můžeme, ale ne při běhu programu.
U každé matice to je totiž jinak (ten algoritmus takhle prostě funguje):
Matice A: N = počet řádků, L = počet sloupců
Matice B: L = počet řádků, M = počet sloupců
Výsledná Matice: N = počet řádků, M = počet sloupců
program Matrix_mult;
uses CRT;
const
N = 2;
L = 2;
M = 2;
type
typ_matice_A = array[1..N, 1..L] of Integer;
typ_matice_B = array[1..L, 1..M] of Integer;
typ_vysledna = array[1..N, 1..M] of Integer;
var
i, j, k: integer;
matice_A: typ_matice_A;
matice_B: typ_matice_B;
procedure maticoveNasobeni(var matice1: typ_matice_A; matice2: typ_matice_B);
var
i, j, k: integer;
vysledna_matice: typ_vysledna;
begin
Write('Vysledna vynasobena matice:');
Writeln;
for i := 1 to N do
for j := 1 to M do
begin
vysledna_matice[i, j] := 0;
for k := 1 to L do
vysledna_matice[i, j] := vysledna_matice[i, j] + (matice1[i, k] * matice2[k, j]);
write(vysledna_matice[i, j]:2,' ');
end;
writeln;
end;
begin
clrscr;
Writeln('=====================================');
Writeln('Vitejte v programu NASOBENI MATIC');
Writeln('=====================================');
Writeln;
Write('Zadejte matici A:[',N,'*',L,']');
Writeln;
for i:=1 to N do
for j:=1 to L do
begin
write('Vlozte clen na pozici [',i,',',j,']: ');
readln(matice_A[i,j]);
end;
Writeln('=====================================');
Writeln('Vami zadana matice A:');
Writeln;
for i:=1 to N do
begin
for j:=1 to L do
begin
write(matice_A[i,j]:2);
end;
writeln;
end;
Writeln('=====================================');
Write('Zadejte matici B:[',L,'*',M,']');
Writeln;
for i:=1 to L do
for j:=1 to M do
begin
write('Vlozte clen na pozici [',i,',',j,']: ');
readln(matice_B[i,j]);
end;
Writeln('=====================================');
Writeln('Vami zadana matice B:');
Writeln;
for i:=1 to L do
begin
for j:=1 to M do
begin
write (matice_B[i,j]:2);
end;
writeln;
end;
Writeln('=====================================');
maticoveNasobeni(matice_A, matice_B);
readln;
end.Jde Ti to zkompilovat? Háže to správné výsledky?
Offline
Offline