Tvorba matic a výstup jejich prvků. 2D pole

Dvourozměrné pole datová struktura, která ukládá obdélníkovou matici formuláře:

A 11 A 12 A 13 A 14 A 15 ... a 1 m A 21 A 22 A 23 A 24 A 25 ... a 2 m A 31 A 32 A 33 A 34 A 35 ... a 3 m A 41 A 42 A 43 A 44 A 45 ... a 4 m A 51 A 52 A 53 A 54 A 55 ... a 5 m ... ... ... ... ... ... ... a n1 A n2 A n3 A n4 A n5 ... a nm

  • V matici je každý prvek určen číslem řádku a číslem sloupce, na jehož průsečíku se nachází
  • V Pascalu je dvourozměrné pole považováno za pole, jehož prvky jsou lineární pole (pole polí). Následující dva popisy dvourozměrných polí jsou identické var mass: pole pole skutečných; var mass: pole skutečných;
  • Volá se matice, ve které je počet řádků roven počtu sloupců čtvercová matice.
  • Chcete-li odkazovat na prvek matice, musíte použít dva indexy označující číslo řádku a číslo sloupce. například MyArr1... V tomto případě je prvek pole (MyArr1) ve čtvrtém řádku a pátém sloupci.
  • Všechno, co bylo řečeno o základních operacích s jednorozměrnými poli, platí také pro matice. Při iteraci nad polem ve smyčce fungují proměnné celočíselného typu jako indexy. Tradičně identifikátor „ i "A sloupec je" j “.
  • Zpracování matice spočívá ve skutečnosti, že nejprve jsou prvky prvního řádku (sloupce) považovány jeden po druhém, poté druhý atd. Až do posledního.
  • Pokud je číslo řádku prvku stejné jako číslo sloupce ( i \u003d j), to znamená, že prvek leží na hlavní úhlopříčka matice.
  • Pokud prvek leží na boční diagonále, pak indexy souvisejí s počtem prvků ( n) následující rovností: i + j \u003d n + 1

Popis dvourozměrného pole

Existuje několik způsobů, jak deklarovat (popsat) dvourozměrné pole v Pascalu.

Předběžný popis typu pole

type matrix \u003d array of integer; (pole celých čísel) var mass: matrix;

Definování proměnné jako pole bez předchozí deklarace typu pole

var mass: pole celého čísla;

Inicializace dvourozměrného pole

Při inicializaci dvourozměrných polí je každý řádek uzavřen v extra dvojici závorek:

Konstantní hmotnost: pole \u003d ((2,3,1,0), (1,9,1,3), (3,5,7,0));

Vstup / výstup hodnot prvků dvojrozměrného pole

Velmi často se hodnoty prvků pole zadávají z klávesnice. Tento způsob zadávání informací je při práci s velkými poli příliš pracný. K ladění široké třídy algoritmů by měl být takový vstup informací nahrazen náhodným generováním prvků pole. Chcete-li to provést, použijte postup náhodně a funkce náhodný... Při práci s dvourozměrnými poli se používají vnořené smyčky (obvykle smyčka s parametrem pro).

Naplnění pole náhodnými čísly

const n \u003d 5; m \u003d 10; var i, j: celé číslo; matice: pole celého čísla; začít náhodně; pro i: \u003d 1 až n do (přístup k řádkům pole) pro j: \u003d 1 až m do (přístup ke sloupcům po prvcích) matrix: \u003d random (100); (do aktuálního prvku vložte náhodné číslo z intervalu: 4); writeln (přechod na nový řádek po opuštění vnitřní smyčky) konec;

Příklady řešení problémů

Příklad 1

Formulace problému. Vzhledem k kladným celým číslům M a N. Vytvořte celočíselnou matici M × N, ve které mají všechny prvky J-tého sloupce hodnotu 5 · J (J \u003d 1, ..., N).

Const m \u003d 7; n \u003d 10; var i, j: byte; matice: pole celého čísla; start for i: \u003d 1 to m do for j: \u003d 1 to n do matrix: \u003d 5 * j; ... (výstupní pole)

Příklad 2

Formulace problému. Vzhledem k kladným celým číslům M, N a množině M čísel. Vytvořte matici M × N, každý sloupec obsahuje všechna čísla z původní sady (ve stejném pořadí).

Const m \u003d 5; n \u003d 7; vektor: pole celého čísla \u003d (3, 5, 2, 7, 4); var i, j: byte; matice: pole celého čísla; begin for j: \u003d 1 to n do (take the j-th column) for i: \u003d 1 to m do (refer to the elements of the j-th column by lines) matrix: \u003d vector [i]; (implementace) ... (Výstup výsledného dvourozměrného pole)

Domácí práce

  1. Vzhledem k kladným celým číslům M a N. Vytvořte celočíselnou matici velikosti M × N, ve které mají všechny prvky prvního řádku hodnotu 10 · I (I \u003d 1, ..., M).
  2. Dostanete kladná celá čísla M, N a sadu N čísel. Vytvořte matici M × N, každý řádek obsahuje všechna čísla z původní sady (ve stejném pořadí).
  3. Dodatečně.Dostanete kladná celá čísla M, N, číslo D a sadu M čísel. Vytvořte matici M × N, ve které se první sloupec shoduje s původní sadou čísel a prvky každého dalšího sloupce se rovnají součtu odpovídajícího prvku předchozího sloupce a čísla D (ve výsledku bude každý řádek matice obsahovat prvky aritmetického postupu).
  4. Dodatečně.Je uvedena matice M × N. Vytiskněte její prvky umístěné v řádcích se sudými čísly (2, 4,…). Výstupní prvky řádek po řádku, nepoužívejte podmíněný operátor.

S dvourozměrným polem v Pascalu se zachází jako s jednorozměrným polem, jehož typem prvku je také pole (pole polí). Poloha prvků v dvourozměrných Pascalových polích je popsána dvěma indexy. Mohou být reprezentovány jako obdélníková tabulka nebo matice.

Zvažte dvourozměrné pole Pascal s rozměry 3 * 3, to znamená, že bude mít tři řádky a každý řádek má tři prvky:

Každý prvek má své vlastní číslo, jako v jednorozměrných polích, ale nyní číslo již sestává ze dvou čísel - čísla řádku, ve kterém je prvek umístěn, a čísla sloupce. Číslo prvku je tedy určeno průsečíkem řádku a sloupce. Například 21 je položka ve druhém řádku a prvním sloupci.

Popis dvourozměrného pole Pascal.

Existuje několik způsobů, jak deklarovat dvourozměrné pole Pascal.

Již víme, jak popsat jednorozměrná pole, jejichž prvky mohou být jakéhokoli typu, a proto mohou být samotnými prvky pole. Zvažte následující popis typů a proměnných:

Příklad popisu dvourozměrného pole Pascal

Typ
Vektor \u003d pole<тип_элементов>;
Matice \u003d pole vektoru;
Var m: matice;

Deklarovali jsme dvourozměrné Pascalovo pole m, skládající se z 10 řádků, každý s 5 sloupci. V tomto případě lze ke každé i-té linii přistupovat m [i] a ke každému j -tému prvku uvnitř i-té linky - m [i, j].

Definice typů pro dvourozměrná pole Pascal lze zadat v jednom řádku:

Typ
Matice \u003d pole pole< тип элементов >;
nebo ještě jednodušší:
typ
matice \u003d pole<тип элементов>;

Odkaz na prvky dvourozměrného pole vypadá takto: M [i, j]. To znamená, že chceme dostat položku umístěnou do i-tého řádku a j-tého sloupce. Hlavní věcí zde není zaměňovat řádky se sloupci, jinak můžeme znovu dostat volání neexistujícího prvku. Například volání prvku M má správnou notaci, ale může způsobit chybu v programu.

Základní operace s dvourozměrnými Pascalovými poli

Všechno, co bylo řečeno o základních operacích s jednorozměrnými poli, platí také pro matice. Jedinou akcí, kterou lze provést na maticích stejného typu jako celek, je přiřazení. To znamená, že pokud náš program popisuje dvě matice stejného typu, například

typ
matice \u003d pole celého čísla;
var
a, b: matice;

pak během provádění programu můžete přiřadit k matici a hodnota matice b (a: \u003d b). Všechny ostatní akce se provádějí prvek po prvku, zatímco na prvcích můžete provádět všechny povolené operace, které jsou definovány pro datový typ prvků pole. To znamená, že pokud se pole skládá z celých čísel, pak lze operace definované pro celá čísla provádět na jeho prvcích, ale pokud se pole skládá ze znaků, jsou pro ně použitelné operace definované pro práci se znaky.

Vstup dvojrozměrného pole Pascal.

Pro postupné zadávání prvků jednorozměrného pole jsme použili smyčku for, ve které jsme změnili hodnotu indexu z 1. na poslední. Ale poloha prvku v dvourozměrném Pascalově poli je určena dvěma indexy: číslem řádku a číslem sloupce. To znamená, že budeme muset postupně změnit číslo řádku od 1. do posledního a v každém řádku iterovat přes prvky sloupců od 1. do posledního. To znamená, že potřebujeme dvě smyčky a jedna z nich bude vnořena do druhé.

Zvažte příklad zadání dvourozměrného pole Pascal z klávesnice:

Příklad programu pro zadávání dvourozměrného pole Pascal z klávesnice

typ
matice \u003d pole celého čísla;
var
a ,: matice;
i, j: celé číslo; (indexy pole)
začít
pro i: \u003d 1 až 5 do (smyčka pro iteraci přes všechny řádky)
readln (a [i, j]); (klávesnicový vstup prvku do i-tého řádku a j-tého sloupce)

Dvourozměrné pole Pascal lze vyplnit náhodně, tj. použijte funkci random (N) a také přiřaďte hodnotu nějakého výrazu každému prvku matice. Způsob vyplnění dvourozměrného pole Pascal je zvolen v závislosti na dané úloze, ale v každém případě musí být definován každý prvek v každém řádku a každém sloupci.

Zobrazí na obrazovce dvourozměrné pole Pascal.

Postupně se vypisují také prvky dvojrozměrného pole Pascal; je nutné tisknout prvky každého řádku a každého sloupce. Současně bych chtěl, aby byly prvky na stejném řádku vytištěny vedle sebe, tj. do řádku a prvky sloupu byly umístěny jeden pod druhým. Chcete-li to provést, musíte provést následující posloupnost akcí (zvažte fragment programu pro pole popsaný v předchozím příkladu):

Příklad programu pro výstup dvourozměrného pole Pascal

pro i: \u003d 1 až 5 do (smyčka pro iteraci přes všechny řádky)
začít
for j: \u003d 1 to 10 do (iterate over all elements of the row by column)
write (a [i, j]: 4); (tisk prvků umístěných v i-té řadě matice v jednom řádku obrazovky, zatímco pro výstup každého prvku jsou přiděleny 4 pozice)
writeln; (před změnou čísla řádku v matici musíte přesunout kurzor na začátek nového řádku obrazovky)
konec;

Poznámka ( to je důležité!): ve studentských programech velmi často dochází k chybě při pokusu o vstup z klávesnice nebo o výstup z pole následovně: readln (a), writeln (a), kde a Je proměnná pole. Jsou však překvapeni zprávou kompilátoru, že proměnnou tohoto typu nelze číst ani tisknout. Možná pochopíte, proč to nelze udělat, když si představíte, že hrníčky řady N stojí v řadě a máte v rukou například rychlovarnou konvici. Dokážete na příkaz „nalít vodu“ naplnit všechny hrnky najednou? Bez ohledu na to, jak moc se snažíte, budete muset nalít do každého hrnku zvlášť. Vyplňování a zobrazování prvků pole by se také mělo provádět postupně a po jednotlivých prvcích, protože v paměti počítače jsou prvky pole umístěny v sekvenčních buňkách.

Dvourozměrná reprezentace pole Pascal v paměti

Prvky abstraktního pole v paměti stroje jsou fyzicky umístěny postupně, podle popisu. Kromě toho každý prvek zabírá v paměti počet bajtů odpovídající jeho velikosti. Například pokud se pole skládá z prvků typu integer, pak každý prvek zabírá dva bajty. A celé pole bude trvat S ^ 2 bajty, kde S je počet prvků v poli.

A kolik místa zabere pole skládající se z polí, tj. matice? Je zřejmé: S i ^ S j, kde S i je počet řádků a S j je počet prvků v každém řádku. Například pro pole jako

Matrix \u003d pole celého čísla;

bude vyžadovat 12 bajtů paměti.

Jak budou umístěny prvky tohoto pole v paměti? Zvažte rozložení pole M matice typu v paměti.

Pro každý prvek M celočíselného typu jsou přiděleny dvě paměťové buňky. Umístění do paměti se provádí „zdola nahoru“. Prvky jsou umístěny v pořadí změny indexu, což odpovídá schématu vnořených smyček: nejprve je umístěn první řádek, potom druhý, třetí ... Uvnitř řádku jsou prvky seřazeny v pořadí: první, druhý atd.

Jak víme, přístup k libovolné proměnné je možný pouze v případě, že je známa adresa paměťové buňky, ve které je proměnná uložena. Když je program načten, je proměnné přidělena specifická paměť, to znamená, že je vytvořena vzájemná korespondence mezi proměnnou a adresou buňky. Pokud jsme ale proměnnou deklarovali jako pole, pak program „zná“ adresu začátku pole, tj. Jeho prvního prvku. Jak přistupujete ke všem ostatním prvkům pole? Se skutečným přístupem k paměťové buňce, ve které je uložen prvek dvojrozměrného pole, systém vypočítá jeho adresu pomocí vzorce:

Addr + SizeElem * Cols * (I -1) + SizeElem * (J -1),

kde Addr je skutečná počáteční adresa, na které je pole umístěno v paměti; I, J - index prvků v dvojrozměrném poli; SizeElem - velikost prvku pole (například dva bajty pro celočíselné prvky); Cols - počet prvků v řádku.

Výraz SizeElem * Cols * (I -1) + SizeElem * (J -1) se nazývá offset od začátku pole.

Kolik paměti je pro pole přiděleno?

Uvažujme ne tolik o otázce, kolik paměti je pro pole přiděleno (diskutovali jsme o tom v předchozí části), ale o tom, jaká je maximální povolená velikost pole, vzhledem k omezenému množství paměti.

Aby program fungoval, je paměť alokována do 64 KB segmentů a alespoň jeden z nich je definován jako datový segment... Právě v tomto segmentu jsou umístěna data, která program bude zpracovávat. Žádnou programovou proměnnou nelze umístit do více než jednoho segmentu. Proto i když v segmentu existuje pouze jedna proměnná popsaná jako pole, nemůže přijmout více než 65536 bajtů. Ale téměř jistě bude v datovém segmentu kromě pole popsáno ještě několik proměnných, takže skutečné množství paměti, které lze pro pole přidělit, zjistíme podle vzorce: 65536-S, kde S je množství paměti již přidělené pro jiné proměnné.

Proč to musíme vědět? Aby nebyl překvapen, pokud překladač během kompilace vygeneruje chybovou zprávu o deklaraci pole, které je příliš dlouhé, když narazí na popis v programu (správné z hlediska syntaxe):

Zadejte myArray \u003d pole celého čísla;

Již víte, že vzhledem k dvoubajtové reprezentaci celých čísel můžete ve skutečnosti deklarovat pole s počtem prvků rovným 65536/2 –1 \u003d 32767. A pak pouze v případě, že neexistují žádné další proměnné. Dvourozměrná pole by měla mít ještě menší hranice indexu.

Příklady řešení problémů s dvourozměrnými Pascalovými poli

Úkol: Najděte produkt nenulových prvků matice.

Rozhodnutí:

  • K vyřešení tohoto problému potřebujeme proměnné: matici skládající se například z celočíselných prvků; P je součinem prvků jiných než 0; I, J - pole indexů; N, M - počet řádků a sloupců v matici.
  • Vstupní data jsou N, M - zadejte jejich hodnoty z klávesnice; matice - zadáme vstup do matice ve formě procedury, vyplníme matici náhodně, tj. pomocí funkce random ().
  • Výstupními daty bude hodnota proměnné P (produkt).
  • Pro kontrolu správnosti provádění programu je nutné zobrazit matici na obrazovce, k tomu vydáme postup pro zobrazení matice.
  • Pokrok v řešení problému:

nejdříve probereme realizaci hlavního programu, implementaci postupů probereme o něco později:

  • zadejte hodnoty N a M;
  • Pojďme si představit dvourozměrné Pascalovo pole, proto se obrátíme na proceduru vvod (a), kde a je matice;
  • Vytiskneme výslednou matici, k tomu odkazujeme na proceduru print (a);
  • Přiřadme počáteční hodnotu proměnné P \u003d 1;
  • Budeme postupně iterovat přes všechny řádky I od 1. do N-tého, v každém řádku budeme iterovat všemi sloupci J od 1. do M-tého, pro každý maticový prvek zkontrolujeme podmínku: if a ij? 0, pak se produkt P vynásobí prvkem a ij (P \u003d P * a ij);
  • Zobrazme hodnotu produktu nenulových maticových prvků - P;

Nyní si promluvme o postupech.

Komentář (to je důležité!) Parametrem procedury může být jakákoli proměnná předdefinovaného typu, což znamená, že k předání pole jako parametru do procedury musí být předem popsán jeho typ. Například:

Typ
Matrix \u003d pole celého čísla;
postup primer (a: matice);
..............................

Vraťme se nyní k našim postupům.

Procedura pro zadávání matice se nazývá vvod, parametr procedury je matice a musí být ve výsledku předán hlavnímu programu, proto musí být parametr předán odkazem. Pak bude záhlaví našeho postupu vypadat takto:

Procedura vvod (var m: matrix);

K implementaci vnořených smyček v proceduře potřebujeme lokální proměnné čítače, například k a h. Algoritmus vyplňování matice již byl diskutován, takže jej nebudeme opakovat.

Procedura pro zobrazení matice na obrazovce se nazývá tisk, parametr procedury je matice, ale v tomto případě se jedná o vstupní parametr, proto se předává hodnotou. Název tohoto postupu bude vypadat takto:

Tisk procedury (m: matice);

A znovu, abychom implementovali vnořené smyčky v rámci procedury, potřebujeme čítače, ať se nazývají stejně - k a h. Algoritmus pro zobrazení matice na obrazovce byl popsán výše, použijeme tento popis.

Příklad programu dvojrozměrného pole Pascal

Program proizvedenie;
Typ
Matrix \u003d pole celého čísla;
Var
A: matice;
N, m, i, j: byte;
P: celé číslo;
Procedura vvod (var m: matrix);
Var k, h: byte;
Začít
Pro i: \u003d 1 až n do (proměnná n pro proceduru je globální, což znamená „známá“)
Pro j: \u003d 1 až m do (proměnná m pro proceduru je globální, což znamená „známá“)
M: \u003d náhodný (10);
Konec;
Tisk procedury (m: matice);
Var k, h: byte;
Začít
Pro i: \u003d 1 až n do
začít
Pro j: \u003d 1 až m do
Zápis (M: 4);
Writeln;
konec;
Konec;
Začátek (začátek hlavního programu)
Writeln ("Zadejte rozměr matice:");
Readln (N, M);
Vvod (a);
Tisk (a);
P: \u003d 1;
Pro i: \u003d 1 až N dělat
Pro j: \u003d 1 až M dělat
Pokud<>0 pak p: \u003d p * a;
Writeln (p);
Konec.

Poslední lekce Pascal byl napsán již 7. března, poté jsme analyzovali. Dnes zjistíme, o co jde dvourozměrné pole v pascalu, jak je to popsáno a co to je. Další podrobnosti níže.

Co přesně je tedy dvourozměrné pole?Pro snadné vnímání reprezentujeme jednorozměrné pole jako čáru, ve kterém všechny prvky jdou vodorovně jeden po druhém, a dvourozměrný jako čtverec, ve kterém jsou prvky umístěny vodorovně i svisle. Dvourozměrné pole se skládá z řádků a sloupců, nazývaných také matice nebo maticové pole.

Jak jsou popsána dvourozměrná pole? Existuje několik způsobů, jak psát dvourozměrná pole, budu uvažovat o 2 z nich.

1 způsob, jak popsat pole: pole typu proměnných v poli (celé číslo / reálné / bajt);

2 způsob, jak popsat pole: pole pole typu proměnných v poli;

Nejprve jsou popsány řádky (1..m) a poté sloupce (1..n).

Druhá metoda popisuje jakoby dvě jednorozměrná pole, která dohromady tvoří jedno dvojrozměrné.

Dvourozměrné pole lze popsat v části Typ, pro další odkaz na něj několikrát, nebo v části popisu proměnné Var, chci poznamenat, že místo m a n můžete nahradit čísla nebo můžete použít konstanty.

Příklad nastavení dvourozměrného pole v sekci deklarace proměnné:

Const
m \u003d 100;
n \u003d 100;
var
a: Pole celého čísla;

V tomto případě jsme nastavili dvourozměrné pole o velikosti 100 na 100, to znamená, že jsme dostali čtvercovou matici.

Příklad definování maticového pole pomocí části Typ:

Const
m \u003d 100;
n \u003d 100;
Typ
Matrix \u003d Array of integer;
var
a: Matrix;
b: Matice;

V druhém příkladu jsme zadali dvě identická maticová pole s rozměry 100 x 100; při popisu pole b jsme nemuseli znovu popisovat jeho velikosti a datový typ.

Jak mohu získat přístup k proměnné buňce dvojrozměrného pole?

Chcete-li odkazovat na dvourozměrné pole, musíte nejprve určit číslo řádku a poté číslo sloupce následujícím způsobem:

x je libovolná proměnná, a je název pole, i je číslo řádku, j je číslo sloupce.

Navíc, i a j mohou být jak proměnné, tak celá čísla.

Příklad zápisu dat do pole:

Pro i: \u003d 1 až n do // nastavte číslo řádku ve smyčce
Pro j: \u003d 1 až m do // přiřazení čísla sloupce ve smyčce
a: \u003d náhodný (100); // přiřazení náhodné hodnoty buňce s číslem řádku i a číslem sloupce j

Pole jsme naplnili náhodnými čísly od 1 do 100.

Ukázkový program využívající dvourozměrné pole, ve kterém pole vyplníme náhodnými čísly a zobrazíme na obrazovce:

Var // popis proměnných a pole
Matice: Pole celého čísla;
i, j: celé číslo;

Začněte // start hlavního programu
writeln ("Dvourozmerne pole:"); // Dialog s uživatelem

Pro i: \u003d 1 až 10 proveďte // vyplnění pole
pro j: \u003d 1 až 10 dělat
Matice: \u003d náhodná (100);

Pro i: \u003d 1 až 10 začněte // Výstup pole
pro j: \u003d 1 až 10 dělat
write (matrix, "");
writeln
writeln ("web"); // Volitelně můžete odstranit
konec; // Konec programu

// readln // Používá se v Turbo Pascal