4. Typ pole4. Typ pole 4.1 Jednorozměrná pole4.1 Jednorozměrná polePole je homogenní datová struktura, skládající se ze složek Pole je homogenní datová struktura, skládající se ze složek
stejného typu. Složky se vzájemně rozlišují pomocí stejného typu. Složky se vzájemně rozlišují pomocí indexu. Indexy složek pole jsou hodnoty určitého typu - indexu. Indexy složek pole jsou hodnoty určitého typu - typ indexu pole, stanoveného popisem pole. Typ složek typ indexu pole, stanoveného popisem pole. Typ složek pole je také stanoven popisem pole, typ není nijak pole je také stanoven popisem pole, typ není nijak omezen - může to být jednoduchý i strukturovaný typ.omezen - může to být jednoduchý i strukturovaný typ.
ordinální typ array [ ] označení typu
, of
popis typu pole
4.1 Jednorozměrná pole 4.1 Jednorozměrná pole
Př.: - deklarace typu poletype var vektor=array[1..3] of real; u,v:vektor; veta=array[0..79]of char; buffer:veta; kod=array[char] of integer; iso:kod;
Hodnoty proměnných typu pole se obvykle mění tak, že se přiřazují hodnoty jednotlivým složkám. Přiřazovacím příkazem je však možné definovat i celou hodnotu proměnné typu pole za podmínky, že pole jsou shodného (pojmenovaného) typu.
Př.:
var u,v : vektor; w : array[1..3] of real; u:=v ... u[1]:=v[1]; u[2]:=v[2]; u[3]:=v[3]; u:=w ... nelze, nejsou stejného typu
Př.: Ukázka naplnění pole
var a : array[1 .. 10] of integer; i : integer;begin for i:=1 to 10 do a[i]:=i;end.
Př.: Ukázka načtení pole v cyklu se známým počtem opakování
var a : array[1 .. 100] of real; i,n : integer; f:text;begin assign(f,'data.txt'); reset(f); read(f,n); for i:=1 to n do read(f,a[i]); for i:=1 to n do begin write(a[i]:8:2); if i mod 5 = 0 then writeln; end;end.
Př.: Ukázka načtení pole v cyklu s neznámým počtem opakování - na vstupu jsou kladná čísla, za nimi záporné
var a : array[1 .. 100] of real; x:real; i,n : integer; f:text;begin assign(f,'data.txt'); reset(f); n:=0; read(f,x); while x>=0 do begin inc(n); a[n]:=x; read(f,x); end; for i:=1 to n do begin write(a[i]:8:2); if i mod 5 = 0 then writeln; end;end.
Př.: Ukázka načtení pole v cyklu s neznámým počtem opakování – do vyčerpání souboru.
var a : array[1 .. 100] of real; i,n : integer; f:text;begin assign(f,'data.txt'); reset(f); n:=0; while not eof(f) do begin inc(n); read(f,a[n]); end; for i:=1 to n do begin write(a[i]:8:2); if i mod 5 = 0 then writeln; end; readln;end.
Př.: Ukázka výpočtu skalárního součinu
var a,b : array[1 .. 10] of real; i,n : integer; ss:real;begin ... ss:=0; for i:=1 to n do ss:=ss + a[i]*b[i]; ...end.
Př.: Ukázka výpočtu hodnoty zadaného polynomu v zadanem bodě (Hornerovo schema)
var a : array[0 .. 30] of real; i,n : integer; x,hp:real;begin assign(f,'data.txt'); reset(f); read(f,n); for i:=n downto 0 do read(f,a[i]); read(f,x); hp:=a[n]; for i:=n-1 downto 0 do hp:=hp*x + a[i]; ...end.
Př.: Vstupní údaje tvoří posloupnost nenulových dvojic reálných čísel - souřadnic bodů v rovině. Posloupnost je ukončena dvojicí nul, která do ní již nepatří. Posloupnost obsahuje maximálně 1000 bodů. Vyjádřete algoritmus pro nalezení souřadnic všech bodů, které jsou nejblíže počátku.
var i,n,imax:integer; xp,yp,v,min:real; x,y:array[1..1000] of real;begin n:=0; min:=1e300; read(xp,yp); while (xp <> 0) or (yp <> 0) do begin inc(n); v:=sqr(xp)+sqr(yp); if v < min then min:=v; x[n]:=xp;y[n]:=yp; read(xp,yp); end; for i:=1 to n do begin v:=sqr(x[i])+sqr(y[i]); if v = min then writeln(x[i]:8:2,y[i]:8:2) end;end.
Př.: Vstupní údaje tvoří posloupnost nenulových dvojic reálných čísel - souřadnic bodů v rovině. Posloupnost je ukončena dvojicí nul, která do ní již nepatří. Posloupnost obsahuje maximálně 1000 bodů. Vyjádřete algoritmus pro zjištění největší vzdálenosti mezi body.
var i,j,n:integer; xp,yp,v,max:real; x,y:array[1..1000] of real;begin n:=0; max:=-1e300; read(xp,yp); while (xp <> 0) or (yp <> 0) do begin inc(n); x[n]:=xp;y[n]:=yp; read(xp,yp); end; for i:=1 to n-1 do for j:=i+1 to n do begin v:=sqr(x[i]-x[j])+sqr(y[i]-y[j]); if v > max then max:=v; end; writeln(sqrt(max):8:2);end.
Př.: Program pro zjištění četnosti výskytu jednotlivých znaků textového vstupu.
program cetnost_znaku;var tab : array['a' .. 'z'] of integer; zn : char;begin for zn := 'a' to 'z' do tab[zn] := 0; while not eof do begin read(zn); if (zn >= 'a') and(zn <= 'z') then tab[zn] := tab[zn] + 1; end; for zn := 'a' to 'z' do writeln(zn,' - ', tab[zn]:5);end.
4.2 Vícerozměrná pole 4.2 Vícerozměrná pole Na typ pole nejsou žádné omezení, složky pole mohou být libovolného Na typ pole nejsou žádné omezení, složky pole mohou být libovolného
strokturovaného typu - i typu pole:strokturovaného typu - i typu pole:
typetype
matice = array[1..10] of array[1..20] of real;...matice = array[1..10] of array[1..20] of real;...
matice = array[1..10,1..20] of real;matice = array[1..10,1..20] of real;
Struktura pole je definována rekurzivně - n-rozměrné pole je pole, jehož Struktura pole je definována rekurzivně - n-rozměrné pole je pole, jehož složky jsou n-1 rozměrná pole. Přístup k jednotlivým složkám: x[1][1][1] ... složky jsou n-1 rozměrná pole. Přístup k jednotlivým složkám: x[1][1][1] ... x[1,1,1]x[1,1,1]
var mat:maticevar mat:matice ... ...
mat[i] je proměnná typu array[1..20] of real - i-tá složka proměnné mat[i] je proměnná typu array[1..20] of real - i-tá složka proměnné
mat - i-tý řádek maticemat - i-tý řádek matice
Př.: Vynulování matice
- průchodem přes všechny prvky
var mat : matice;...for i:=1 to 10 do for j:=1 to 20 do mat[i,j]:=0; {200x}
- kopírováním celého vektoru
var mat : matice;...for i:=1 to 20 do mat[1,i]:=0; {20x}for i:=2 to 10 do mat[i]:=mat[1]; {9x}
Př.: Výměna dvou řádků matice
- průchodem přes všechny prvky
var mat : array[1..10,1..20] of real; pom : real;
for j:=1 to 20 do begin pom:=a[k,j]; a[k,j]:=a[l,j]; a[l,j]:=pom; {60x}end; - kopírováním celého vektoru
type radek=array[1..20] of real; matice=array[1..10] of radekvar mat : matice; pom : radek;...pom:=mat[k]; mat[k]:=mat[l]; mat[l]:=pom; {3x}
Proměnné pom a mat[i] musí být stejného (pojmenovaného) typu - radek, nestačí pouze stejný rozměr.
program nasobeni_matic;var a,b,c : array[1..10,1..10] of real; i,j,k,n : integer; s : real;begin read(n); for i := 1 to n do for j := 1 to n do read(a[i,j]); for i := 1 to n do for j := 1 to n do read(b[i,j]); for i := 1 to n do for j := 1 to n do begin s := 0; for k := 1 to n do s := s + a[i,k] * b[k,j]; c[i,j] := s; end; for i := 1 to n do begin {tisk dvou matic vedle sebe} for j := 1 to n do write(a[i,j]); write(' '); for j := 1 to n do write(b[i,j]); writeln; end; for i := 1 to n do begin {tisk matice} for j := 1 to n do write(a[i,j]); writeln; end;end.
Př.: V zadané obdélníkové matici najděte všechny řádky, které tvoří navzájem kolmé vektory.
program kolme_radky_matice;var a : array[1..10,1..10] of real; i,j,k,m,n : integer; s : real;begin read(m,n); for i := 1 to m do for j := 1 to n do read(a[i,j]); for i := 1 to m-1 do for j := i+1 to m do begin s := 0; for k := 1 to n do s := s + a[i,k] * a[j,k]; if s=0 then writeln('Radky ',i,' a ',j,' jsou kolme'); end;end.
Př.: V zadané obdélníkové matici najděte sloupec s největším součtem.
program max_soucet_slouce;var a : array[1..10,1..10] of real; i,j,m,n,jmax : integer; s,max : real;begin read(m,n); for i := 1 to m do for j := 1 to n do read(a[i,j]); max:=-1e30; for j := 1 to n do begin s:=0; for i := 1 to m do s:=s + a[i,j]; if s > max then begin max:=s; jmax:=j; end; end; writeln('Nejvetsi soucet ',s:8:2,' je ve sloupci ',jmax);end.
4.3 Řetězce 4.3 Řetězce V pascalu je definován typ packed array of char - kompresované pole znaků, který neni v TP implementován. Obyčejné pole znaků je pro ukládání řetězců nepraktické. V TP je definován speciální typ řetězec - string.Hodnota proměnné typu string je posloupnost znaků s atributem aktuální délky řetězce (momentální délka řetězce během vykonávání programu) a s atributem konstantní délky řetězce v rozsahu 0..255.
Př.:
type string8=string[8];
var s1,s2 : string8; s : string;
4.3 Řetězce 4.3 Řetězce I- tý znak řetězce je zpřístupněn pomocí indexu .Zápis s[i] znamená hodnotu typu char. Proměnná i může nabývat hodnot z intervalu od 0 po velikost atributu konstantní délky.Řetězec délky n je tedy definován jako pole znaků o n+1 prvcích. První znak řetězce s[0] je znak, jehož ordinální číslo (ASCII kod) představuje skutečnou délku řetězce - atribut aktuální délky.
Pro zjištění aktuální délky řetězce slouží funkce length(s), která je ekvivalentní výrazu ord(s[0]).
Znaky za dynamickou délkou jsou náhodné. Je možno k nim přistupovat pomocí indexu - kompilátor nekontroluje překročení indexu přes aktuální délku.
Operace s řetězci: Operace s řetězci: - operace zřetězení dvou řetězců :
var s1, s2: string;... s1 + s2
- Výsledek je řetězec délky, která je součtem délek s1 a s2; je-li součet délek větší než atribut konstantní délky proměnné, do níž se má uložit, je přebytečná část stracena.
- relační operace:
=,<>,<,>,>=,<=
- porovnávají řetězce znak po znaku podle jejich ordinálních čísel. U nestejně dlouhých řetězců se považuje každý znak, který nemá partnera za větší: ‘xxa’>‘xx’.Konstanty typu řetězec se zapisují v jednoduchých uvozovkách 'abc', prázdný řetězec ''.
Podprogramy pro práci s řetězci Podprogramy pro práci s řetězci Procedury: delete, insert, str, val.Funkce: concat, copy, length, pos.
Delete - vypuštění podřetězce z řetězce:
procedure delete(var s:string; index,count:integer);
- z řetězce s vypustí od pozice index počet znaků daný count.
s:='123456789';delete(s,3,4); {... s='12789'}
Insert - vložení podřetězce do řetězce
procedure insert(source:string; var s:string; index:integer);
- do řetězce s vloží od pozice index řetězec source.
s:='12789';insert('3456',s,3); {... s='123456789'}
Podprogramy pro práci s řetězci Podprogramy pro práci s řetězci
Str - převádí numerickou hodnotu (reálnou nebo celočíselnou) na výraz typu string, formát výsledku je stejný jako u write
procedure str(x[:i[:j]]; var s:string);
str(1.2345:8:3,s) ... s='~~~1.235'
Val - převádí řetězec na číslo (reálné nebo celé)
procedure val(s:string; var v:; var code:integer);
s musí obsahovat syntakticky správný zápis čísla typu real nebo integer; dojde-li při převodu k chybě, vrací proměnná code pozici nesprávného znaku v řetězci. Před číslem nesmí být mezery. Proměnná v musí být odpovídajícího typu.
val('1.23',r,c); val'123',i,c);
Podprogramy pro práci s řetězci Podprogramy pro práci s řetězci
Concat - spojení více řetězců do jednoho
function concat(s1[,s2,...,sn]:string):string;
s:=concat('123','456','789'); ... s='123456789'
Copy - výběr podřetězce z řetězce
function copy(s:string;index,count:integer):string;
funkce vrací podřetězec z řetězce s od pozice index délky count
s:='123456';s:=copy(s,3,2); {... s='34'}
Podprogramy pro práci s řetězci Podprogramy pro práci s řetězci
length - délka řetězce
function length(s:string):integer;
pos - prohledá řetězec na výskyt podřetězce
function pos(substr,s:string):integer;
Vyhledá první pozici výskytu podřetězce v řetězci, není-li nalezen, vrací nulu.
Př.: Nahrazení mezer před číslem nulami
s:='~~~1.234';while pos('~',s)>0 do s[pos('~',s)]:=0; {... s='0001.234'}
Př.: Odstranění mezer z řetězce
s:='~~~1.234~';while pos('~',s)>0 do delete(s,pos('~',s),1); {... s='1.234'}
var s1,s2:string; i:integer;
s1:='~~~1.234~'; s2:='';for i:=1 to length(s1) do if s1[i] <> '~' then s2:=s2+s1[i];
Podprogramy pro práci s řetězci Podprogramy pro práci s řetězci
Př.: Převrácení řetězce
var s1,s2 : string; i,n : integer;begin readln(s1); n := length(s1); for i := 1 to n do s2[i] := s1[n-i+1]; s2[0]:=chr(n); writeln(s2);end.
var s1,s2 : string; i,n : integer;begin readln(s1); n := length(s1); s2:=''; for i := 1 to n do s2 := s2 + s1[n-i+1]; writeln(s2);end.
5. Deklarace typů, výčtový typ, typ interval5. Deklarace typů, výčtový typ, typ interval
Datový typ představuje atribut datového objektu, specifikujícímnožinu přípustných hodnot a množinu přípustných operací. Existuje sedum tříd typů:
- výčtový- interval - množina- pole- záznam- soubor- ukazatel
Každá třída má zavedenu konstrukci, pomocí níž se definují konkrétní typy této třídy
Př.: array[boolean] of integer.
Deklarace typů, výčtový typ, typ intervalDeklarace typů, výčtový typ, typ interval Popis typu se může vyskytovat jako označení typu v deklaraci proměnné (tzv. nepojmenované typy) nebo se typ definuje společně s jeho jménem - identifikátorem typu. (pojmenované typy). Pojmenované typy se zavádějí v úseku deklarace typů.
Př.:
type index=1..50; vektor=array[index] of integer; znaky=set of char; vekt=array[index] of integer;
Deklarace se skládá z identifikátoru typu a popisu typu. Pro typovou kontrolu je důležité, že každým výskytem popisu typu se definuje nový typ různý od všech ostatních ... vekt<>vektor.
var x:array[index] of integer;
... proměnná x nepojmenovaného typu, který je různý od vekt a vektor.
Výčtový typVýčtový typ
Tento typ se používá v případě potřeby vyjádřit malý počet hodnot. Jeho použití zvyšuje čitelnost a srozumitelnost programu. Symbolické hodnoty můžeme kódovat pomocí přirozených čísel 0,1,2, ... nebo využitím výčtového typu.
Př.:type stav = (svobodny,zenaty,rozvedeny,vdovec); den = (pondeli,utery, ... ,nedele);
Výčtový typ je ordinální typ a jsou pro něj definovány relační operace a standardní funkce ord, succ, pred. Uspořádání hodnot výčtového typu je dáno poředím identifikátorů v definičním seznamu. První položka má nejmenší hodnotu, její ordinální číslo je 0.
Př.:ord(pondeli)=0, ord(utery)=1, utery<streda, succ(utery)=streda.
Výčtový typVýčtový typ
Pro výčtový typ nejsou definovány žádné další operace. Chceme-li provést výpis hodnot výčtového typu:
var s:den;...case s of pondeli : writeln('pondeli'); utery : writeln('utery');...end;
Typ interval Typ interval
Specifikuje neprázdnou souvislou podmnožinu hodnot nějakého ordinálního typu. Interval je určen dolní a horní mezí , které jsou tvořeny konstantami daného typu:
type tden = (pondeli,utery,....nedele); tcislice = '0' .. '9'; tpracden = pondeli .. patek; tkladna_cisla = 1 .. maxint; tzaporna_cisla = -maxint .. -1;
Typ interval Typ interval
Deklaraci proměnné typu interval provedeme pomocí pojmenovaného typu nebo přímo:
var pocet : 1 .. 100; pracden : pondeli .. patek;
Stanovením intervalu jako typu proměnné se omezuje množina přípustných hodnot proměné. Kontrola přípustnosti se provádí obvykle až v době výpočtu.