400 likes | 578 Views
Informatyka 2 MPDI. Wyk ł ad 9. Delphi tablice, rekordy. Typ tablicowy ( array ). Pojęcie : - skończony zbiór elementów tego samego typu składowego (homogeniczne) - o położeniu ( selekcji ) określanym przez indeks(-y) ( numery) składowej. Opis :.
E N D
Informatyka 2 MPDI Wykład 9 Delphi tablice, rekordy
Typ tablicowy (array) Pojęcie: - skończony zbiór elementów tego samego typu składowego (homogeniczne) - o położeniu (selekcji) określanym przez indeks(-y)(numery) składowej Opis: array [ lista typów indeksów ]of typ bazowy (składowych) typ porządkowy (o ograniczonym zakresie): • okrojony integer (najczęściej) • okrojony char • wyliczeniowy • boolean dowolny: • prosty • strukturalny (bez plików) tablica tablic,napisów, rekordów
Uwagi • tablice służą do gromadzenia wielu wartości tego samego typu (nietrwałe – tylko w pamięci operacyjnej – później poznamy jak zapisywać do plików) • wymiar tablicy • 1-wymiarowa -wektor • 2-wymiarowa (prostokątna) • 3-wymiarowa (przestrzenna) itd.. • rozmiar – w każdym wymiarze! • zawartość – dowolna – także inna tablica! • np. • array [1..5,1..5] of array [1..2,1..2] of integer;
przykłady: array[ 1..50 ] ofinteger; array[ 1..20, 1..30] of real; array[ 1..20] ofarray[ 1..30] of real; może być też 30 wierszy i 20 kolumn, zależy od wizualizacji
Tablica ma: • wymiar • rozmiarw każdym wymiarze • mogą być indeksy ujemne array [ -10 .. 0 ] of real
Zmiennetablicowe indeksowane (składowe) całościowe
zmienne indeksowane (składowe) - dostęp do składowych Z [ W1, ..., Wn ] Wtypu składowego nazwa tablicy indeksy wyrażenia typu zgodnego z typem indeksów zgodne co do liczby, typu i kolejności z deklaracją • użycie - w wyrażeniach lub instrukcjach, jak zmienne typu składowego Przykłady: var x: array[ 1..100 ] ofreal; begin x[ 2 ] := 10.5; //nadanie wartości y := 10*x[ k ] - 5.2; //użycie w wyrażeniu z:=sin( sqrt( x[ 5 ] - 5.2 ) )//użycie w wyrażeniu if x[5] >0 then .... //sprawdzenie
zmienne całościowe - tylko przypisanie - dla typów tożsamych! brak: + - * / porównania np: var x, y: array[ 1..5] of integer ; begin y[1] := 35 ; x := y; //przepisz całą zawartość tablicy y do tablicy x ..... end
Nadanie wartości początkowych zmiennym tablicowym • dla tablic konstrukcja typu: ( (st11, st21,..., stn1 ), (st12, st22,..., stn2 ), . . . (st1m, st2m,..., stnm) ) const osoby: array[ 1..3] ofstring[20] = ( 'Nowak', 'Kowalski', 'Nycz' ); albo zmienna (zmiennym można w programie zmienić wartości a stałym NIE): var wyniki: array[ 1..3, 1..4] ofreal = ( ( 3, 4, 4.5, 5), ( 2, 3.5, 5.0, 4.5), (5.0, 4, 3.5, 2) );
Przykład: program p2; {APPTYPE CONSOLE} usesSysUtils; var wyniki: array[ 1..3, 1..4] of real = (( 3, 4, 4.5, 5), ( 2, 3.5, 5.0, 4.5), (5.0, 4, 3.5, 2)); begin writeln (wyniki[1,1]:10:2); //wypisze wartość 3.00 readln; end.
Przykłady operacji tablicowych type tab = array [1..2, 1..5] of real; var t1, t2 : tab; wie,kol: integer; begin write ('Podaj element 1,1:'); readln(t1[1,1]); //itd. // najczęściej operacje w pętli zagnieżdżanej jeśli tablica 2-wymiarowa for wie:=1 to 2 do for kol:= 1 to 5 do t1[wie, kol] :=1; //wyświetlenie na ekranie też w pętli zagnieżdżanej for wie:=1 to 2 do begin for kol:= 1 to 5 do write(t1[wie, kol]); writeln; end; readln; end. cała tablica wypełniona jedynkami pętla zewnętrzna po wierszach pętla wewnętrzna po kolumnach każdego wiersza po wypisaniu wiersza tabeli przejdź do nowego wiersza
Zadanie: w wektorze zsumować co drugi element (nieparzyste indeksy) program test; constN=12; type zakres = 1..N; var k: zakres; suma: real; x: array [ 1 .. N ] of real= ( 3, 4, 4.5, 5, 2, 3.5, 5.0, 4.5, 5.0, 4, 3.5, 2); begin suma := 0; for k := 1 to N do if (k mod 2) = 1 then suma := suma + x [k]; writeln ( suma :10:3) ; readln end. zastanowić się! albo można tak: for k := 1 to ( N+1 ) div 2 do suma := suma + x [ 2*k - 1 ];
Pamiętajmy: Nie ma gotowych operacji macierzowych (mnożenie, obliczanie wyznacznika, znajdowanie macierzy odwrotnej itp.), trzeba samemu stworzyć algorytm lub posiadać odpowiednie biblioteki z gotowymi podprogramami Przykładowo mnożenie tablic: program mn24; var t1:array[1..2, 1..4] of real = ((1,2,4,-1),(0, -1, 8, 1)); t2 :array[1..4,1..2] of real = ((1,1.1),(4,-2.0),(0, -1),(-3,-2.5)); wyn: array[1..2,1..2] of real; i:1..4; begin // obliczanie elementu 1,1 wyn[1,1]:=0; for i:=1 to 4 do wyn[1,1]:= wyn[1,1]+ t1[1,i]*t2[i,1]; writeln(wyn[1, 1]:10:2); readln; end.
Całość: program mn24; const N=2; M=4; var t1:array[1..N, 1..M] of real = ((1,2,4,-1),(0, -1, 8, 1)); t2 :array[1..M,1..N] of real= ((1,1.1),(4,-2.0),(0, -1),(-3,-2.5)); wyn: array[1..N,1..N] of real; wie,kol, i:1..4; begin //potrójna pętla! for wie:=1 to N do for kol:=1 to N do for i:=1 to M do wyn[wie,kol]:= wyn[wie,kol]+ t1[wie,i]*t2[i,kol]; //wyswietlenie wyniku for wie:=1 to N do begin for kol:= 1 to N do write(wyn[wie, kol]:10:2); //wypisanie wiersza writeln; //zmiana wiersza end; readln; end.
Można wyświetlać wyniki od razu po utworzeniu elementu ... begin //potrójna pętla! for wie:=1 to N do begin for kol:=1 to N do begin //utworzenie elementu for i:=1 to M do wyn[wie,kol]:= wyn[wie,kol]+ t1[wie,i]*t2[i,kol]; // i od razu wyświetlenie write(wyn[wie, kol]:10:2); end; writeln; end; readln; end.
Pamiętamy typ string – typ łańcuchowy – zmienna zawiera ciąg znaków Można typ string traktować jako wektor znaków string[20] tożsame z array[0..20] of char; varzmienna:string[20]; begin zmienna:= 'lokomotywa'; writeln (zmienna[3]); { wyświetli literę k } {…..} end.
Przeszukiwanie tablic jednowymiarowych • Algorytm przeszukiwania tablic polega na porównywaniu podanego wzorca z kolejnymi elementami tablicy. • Pseudokod algorytmu wygląda następująco. • 1. Start. • 2. Wczytaj tablicę i wzorzec przeszukiwań. • 3. Ustaw licznik na wartość 1. • 4. Sprawdź czy wzorzec jest równy elementowi tablicy o indeksie równym licznikowi. Jeżeli tak to przejdź do punktu 7, jeśli nie to kontynuuj. • 5. Zwiększ licznik o 1. • 6. Sprawdź czy licznik nie jest większy od rozmiaru tablicy. Jeśli tak, to napisz, że nie znaleziono wzorca i przejdź do punktu 8, jeśli nie to przejdź do punktu 4. • 7. Wypisz licznik i element o indeksie równym aktualnemu licznikowi. • 8. Stop. Oczywiście algorytm znajdzie tylko pierwsze wystąpienie – co zrobić gdy w tablicy elementy się powtarzają?
Wyznaczanie minimum (maksimum) Algorytm przeszukiwania tablic polega na początkowym założeniu, że minimum (maksimum) X jest pierwszym elementem tablicy. Następnie kolejno sprawdzamy elementy od 2 do N - jeśli analizowany element jest mniejszy (większy) od aktualnego X ustawiane jest nowe X. Pseudokod algorytmu wygląda następująco. • 1. Start. • 2. Wczytaj tablicę. • 3. Przypisz pierwszy element tablicy do Emin. • 4. Zwiększ licznik o 1. • Sprawdź czy licznik nie jest większy od rozmiaru tablicy. Jeśli tak, przejdź do punktu 9. • Sprawdź czy aktualny element jest mniejszy od Emin.Jeśli tak wstaw go do Emin. • Przejdź do punktu 4. • 9. Wypisz Emin. • 10. Stop.
program maximum; {$APPTYPE CONSOLE} usesSysUtils; var x:array[1..20] of integer; k,max:1..20; begin randomize; for k:=1 to 20 do // losowe wypełnienie tablicy begin x[k]:= random(100); write(x[k]:5); end; max:= x[1]; for k:=2 to 20 do if x[k]>max thenmax:=x[k]; writeln; writeln(max:10); readln; end.
Sortowanie bąbelkowe Algorytm polega porównywaniu kolejnych par elementów sąsiadujących i zamianie miejscami w przypadku niewłaściwej kolejności. Po wykonaniu pierwszego przebiegu porównań i ewentualnych zamian miejscami, element największy znajdzie się na końcu (w przypadku porządku sortowania według kolejności rosnącej). Następnie wykonujemy kolejny przebieg porównań par i tak dalej…
Sortowanie Sortowanie bąbelkowe Algorytm polega porównywaniu kolejnych par elementów sąsiadujących i zamianie miejscami w przypadku niewłaściwej kolejności 1 2 3 4 ..... N N-1 porównań w każdym przebiegu Wykonujemy N przebiegów
1 przebieg 12 5 11 4 7 2 zamiana 1 5 12 11 4 7 2 zamiana 2 5 11 12 4 7 2 zamiana 3 5 11 4 12 7 2 zamiana 4 5 11 4 7 12 2 zamiana 5 5 11 4 7 2 12efekt ostatniej zamiany – największy na końcu 2 przebieg 5 11 4 7 2 12 5 11 4 7 2 12 zmiana 6 5 4 11 7 2 12 zmiana 7 5 4 7 11 2 12 zmiana 8 5 4 7 2 11 12 5 4 7 2 11 12 3 przebieg 5 4 7 2 11 12 zamiana 9 4 5 7 2 11 12 4 5 7 2 11 12 zamiana 10 4 5 2 7 11 12 4 5 2 7 11 12 4 5 2 7 11 12 4 przebieg 4 5 2 7 11 12 4 5 2 7 11 12 zamiana 11 4 2 5 7 11 12 4 2 5 7 11 12 4 2 5 7 11 12 4 2 5 7 11 12 N=6 zauważamy nadmiarowe porównania
5 przebieg 4 2 5 7 11 12 zmiana 12 2 4 5 7 11 12 2 4 57 11 12 2 4 5 711 12 2 4 5 7 11 12 2 4 5 7 11 12 6 przebieg 2 4 5 7 11 12 2 4 5 7 11 12 2 4 5 7 11 12 2 4 5 7 11 12 2 4 5 7 11 12 30 operacji= (N-1)*N=6*5
Sortowanie bąbelkowe skrócone Algorytm polega na porównywaniu kolejnych par elementów sąsiadujących, z tym, że: - w każdym kolejnym przebiegu liczba analizowanych par jest zmniejszana o 1 - przebiegów wykonujemy N-1
1 przebieg 12 5 11 4 7 2 zamiana 1 5 12 11 4 7 2 zamiana 2 5 11 12 4 7 2 zamiana 3 5 11 4 12 7 2 zamiana 4 5 11 4 7 12 2 zamiana 5 5 11 4 7 2 12 efekt 2 przebieg 5 11 4 7 2 12 5 11 4 7 2 12 zamiana 6 5 4 11 7 2 12 zamiana 7 5 4 7 11 2 12 zamiana 8 5 4 7 2 11 12 efekt 3 przebieg 5 4 7 2 11 12 zamiana 9 4 5 7 2 11 12 4 5 7 2 11 12 zamiana 10 4 5 2 7 11 12 efekt 4 przebieg 4 5 2 7 11 12 4 5 2 7 11 12 zamiana 11 4 2 5 7 11 12 efekt 5 przebieg 4 2 5 7 11 12 zamiana 12 2 4 5 7 11 12 efekt 5 4 15 operacji 3 2 1
const N=10; vartab:array [1..N] of integer; k, m:1..N; pom, lop:integer; begin randomize; //wypełnienie losowe tablicy 1-wymiarowej for k:=1 to N do tab[k]:=random(100); //sortowanie for k:=1 to N do for m:=1 to N-1 do begin lop:=lop+1; iftab[m]>tab[m+1] then begin pom:=tab[m]; tab[m]:=tab[m+1]; tab[m+1]:=pom; end; end; //wypisanie wyniku for k:= 1 to N do write(tab[k]:6); writeln;writeln(lop); readln; end. Bąbelkowe zamiana wartości tab[m] i tab[m+1] lop=90
const N=10; vartab:array [1..N] of integer; k,m:1..N; pom,lop:integer; begin randomize; //wypełnienie losowe tablicy 1-wymiarowej for k:=1 to N do tab[k]:=random(100); //sortowanie for k:=1 to N-1 do for m:=1 to N-k do begin lop:=lop+1; iftab[m]>tab[m+1] then begin pom:=tab[m]; tab[m]:=tab[m+1]; tab[m+1]:=pom; end; end; //wypisanie wyniku for k:= 1 to N do write(tab[k]:6); writeln;writeln(lop); readln; end. Bąbelkowe skrócone różnice! lop=45 szybsze
Typ rekordowy (record) • pojęcie: - skończony zbiór elementów dowolnego typu składowego tak zwane pola - ułożone jednowymiarowo - o położeniu (selekcji) określanym przez nazwęskładowej (pola) - tzw. dostęp kwalifikowany Czyli zestaw nazwanych pól dowolnego typu (i różnego rozmiaru)
opis: record lista_nazw_pól: typ1; lista_nazw_pól: typ2; . . . end typ dowolny: prosty lub strukturalny (bez plików) pole może byćliczbą, tekstem, tablicą, napisem, innym rekordem
Przykłady: typedata = record rok: 1900 .. 2100; mies: 1..12; dzien: 1..31 end; varstudent : record nazw: string[ 20 ]; imie: array[1..2] of string[ 15 ]; data_ur: data; stypend: real end;
Porównanie: • jednakowe składowe • selektor typu indeks • dostęp bezpośredni • statyczny rozmiar • różne składowe • selektorem jest nazwa pola • dostęp bezpośredni • statyczny rozmiar Uwaga: Rekord to jeden zestaw danych (np. dane jednego studenta), jeśli potrzebujemy analizy większej liczby to tworzymy tablicę rekordów
Deklaracje (opis) zmiennych Zmienna tablicowa var t1:array [1..5, 1..6] of real; Zmienna rekordowa varstudent : record nazw: string[ 20 ]; imie: array[1..2] of string[ 15 ]; stypend: real end; typedane =record nazw: string[ 20 ]; imie: array[1..2] of string[ 15 ]; stypend: real end; var student: dane; lub
Wykorzystanie zmiennych rekordowych w programie • zmienne całościowe - tylko przypisanie – możliwe jedynie dla typów tożsamych czyli dokładnie takie same składowe! brak: + - * / porównania wejścia/wyjścia – wczytać lub wypisać można tylko składową (pole) • np: var r1, r2: record ..definicja... end ; begin //… ustalenie zawartości zmiennej r1 r2 := r1; //przepisz zawartość r1 do r2
desygnator pola (składowa) - dostęp do pola Z . p Ztypu składowego nazwa zmiennej rekordowej nazwa pola UWAGA: kropka oddzielająca!
Przykład1 typedata= record dzien, miesiac, rok:integer end; varstudent:record nazw: string[ 20 ]; imie: array[1..2] of string[ 15 ]; data_ur: data;//zdefiniowany typrekordowy stypend: real end; begin student.nazw:= 'Kowalski'; student.stypend:= 300; student.data_ur.dzien:= 3; student.data_ur.rok := 1993; student.imie[1]:= 'Jan'; writeln(student.imie[1][2] ) ; //to 2-ga litera 1-go imienia //itd. definicje użycie: w wyrażeniach lub instrukcjach, w zależności od typu składowej program
Przykład2: program test; typedata= record dzien, miesiac, rok:integer end; varstudent:record nazw: string[ 20 ]; imie: array[1..2] of string[ 15 ]; data_ur: data; stypend: real end; begin write('Podaj imię1:'); readln(student.imie[1]); write('Podaj drugie imię:'); readln(student.imie[2]); write('Podaj dzien urodzenia:'); readln(student.data_ur.dzien); //itd. writeln(student.imie[1]); //wypisz na ekranie //itd. end.
Użycie elementów tablicy i rekordu w części wykonawczej programu: tablica t1[5, 6] indeks (-y) rekordstudent.nazwisko student.imie[1] student.data_ur.rok w zależności od typu nazwy pól zmienna
TABLICE REKORDÓW Tablice rekordów służą do gromadzenia wielu danych typu rekordowego (zwykle 1-wymiarowe) type data = record rok: 1900 .. 2100; mies: 1..12; dzien: 1..31 end; osoba = record nazw: string[ 20 ]; imie: array[1..2] of string[ 15 ]; data_ur: data; end; varos1:osoba; // zmienna rekordowa pomocnicza grupa: array[1..100] ofosoba; //tablica rekordów !!!!
grupa – zmienna typu tablicowego grupa[k] – zmienna typu rekordowego grupa[1].nazw - zmienna typu string grupa[2].imie – zmienna typu tablicowego grupa[k].imie[1] - zmienna typu string grupa[k].data_ur - zmienna typu rekordowego grupa[k].data_ur.rok – zmienna typu integer grupa[2].imie[2][5] – zmienna typu char Użycie zależne od typu: writeln( grupa[3].nazw); os1.nazw := 'Nowak'; grupa[50]:=os1; os1:= grupa[51]; writeln (grupa[k].imie[1]); writeln(length(grupa[30].nazw)) ifgrupa[k].data_ur.rok>1970 then…
Instrukcja wiążąca - with • dotyczy tylko zmiennych rekordowych (obiektowych) • upraszcza zapis !! Opis: withlista_zmiennych_rekordowych doinstrukcja; najczęściej begin . . . end można tu używać nazw pól bez specyfikowania zmiennej rekordowej przykład: withstudent do begin nazw :='Kowalski'; imie[1] := 'Jan'; data_ur.rok := 1988; stypendium := 420.0; end; student.nazw:='Kowalski'; student.imie[1] := 'Jan'; student.data_ur.rok := 1988; student.stypendium := 420.0;