Střední škola stavební Jihlava
Sada 1 - Základy programování 13. Práce s řetězci - palindrom Digitální učební materiál projektu: SŠS Jihlava – šablony registrační číslo projektu:CZ.1.09/1.5.00/34.0284 Šablona: III/2 - inovace a zkvalitnění výuky prostřednictvím ICT
Jaromír Železný © 2013
Projekt je spolufinancován Evropským sociálním fondem a státním rozpočtem České republiky
Strukturované datové typy • pokud mají data určitou společnou vlastnost a jsou určitým způsobem organizována, říkáme o nich, že tvoří struktury • Strukturované datové typy: 1) Řetězec 2) Pole a) jednorozměrné b) vícerozměrné (nejčastěji dvou-, tří-) 3) Záznam 4) Množina 5) Soubor
Řetězec znaků • jeden znak = datový typ CHAR • řetězec = datový typ STRING • CHAR = jeden znak • STRING = řetězec dlouhý 255 znaků • při deklarování proměnné jako string se v paměti rezervuje (vyhradí) prostor pro 255 znaků, který můžeme využít
Řetězec znaků • pokud jsme si ale jisti, že do dané proměnné nebudeme tak dlouhá řetězec ukládat, můžeme velikost rezervovaného prostoru upravit při deklaraci var Jmeno:String[15]; • takto deklarovaná proměnné nebude mít vyhrazený prostor pro 255 znaků, ale pouze pro 15 znaků • pokud bychom do této proměnné chtěli uložit delší řetězec, příkaz by vyvolal chybu.
Řetězec znaků • znaky v řetězci jsou uloženy odděleně, můžeme k nim přistupovat jednotlivě • každé políčko řetězce má svů index = své pořadové číslo • jednotlivé znaky můžeme vypisovat, ale také je měnit
Řetězec znaků Program TEST; Var jmeno:string[5]; Begin Jmeno:=‘Pavla‘; Writeln (Jmeno); Writeln (Jmeno[1]); Writeln (Jmeno[2]); Writeln (Jmeno[3]); Writeln (Jmeno[4]); Writeln (Jmeno[5]); Writeln; Jmeno[4] :=‘e‘; Jmeno[5] :=‘l‘; Writeln (Jmeno); Readln; End.
Řetězec znaků • funkce LENGTH(RETEZEC) vrací počet znaků v řetězci • funkce CHR(CISLO) vrací znak podle hodnoty CISLO z tabulky ASCII • funkce ORD(ZNAK) vrací číslo znaku ZNAK z tabulky ASCII • funkce UPCASE(ZNAK) převede malé písmeno na velké • funkce LOWERCASE(ZNAK) převede velké písmeno na malé (lze použít ve Free Pascalu – v TP pomocí ORD(x) - 32)
Tabulka ACSI kódů kód 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
znak mezera ! '' # $ % & ' ( ) * + , – . /
kód 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
znak 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
kód 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
znak @ A B C D E F G H I J K L M N O
kód 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
znak P Q R S T U V W X Y Z [ \ ] ^ _
kód 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
znak ` a b c d e f g h i j k l m n o
kód 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
znak p q r s t u v w x y z { | } ~ del
Kódy s hodnotami 0 až 31 se většinou nezobrazují jako konkrétní znaky (to záleží na daném programu), jsou určeny jako řídící kódy pro různé periférie (monitor, tiskárna apod.) anebo mají konkrétní význam – např. přechod textu na novou řádku, pípnutí apod.
Řetězec znaků • funkce COPY(RETEZEC,INDEX,POCET) vrací POCET znaků do konce řetězce RETEZEC počínaje znakem na pozici INDEX • funkce CONCAT(s1,[s2, …, sn]) spojuje řetězce s1, s2,…, sn v jeden řetězec, je-li výsledek delší než 255 znaků, je zkrácen na 255 znaků
Řetězec znaků • procedura DELETE(RETEZEC,INDEX,POCET) odstraní POCET znaků z řetězce RETEZEC počínaje znakem na pozici INDEX • procedura INSERT(ZDROJ,RETEZEC,INDEX) vloží do řetězce RETEZEC od pozice INDEX řetězec ZDROJ • procedura STR(CISLO,RETEZEC) převede číslo CISLO na řetězec RETEZEC • procedura VAL(RETEZEC,CISLO, Err_Code) převede řetězec RETEZEC na číslo CISLO
Řetězec znaků • Př.: napište program, kterým převrátíme řetězec. Ve výstupu bude první znak na posledním místě, druhý na předposledním,… a poslední znak z původního řetězce bude na prvním místě.
Řetězec znaků - program • Postup: 1. Stanovíme si, co má program dělat, tzn. si určíme, co má být vstupem a výstupem. Na vstupu je jakýkoliv řetězec o maximální délce 255 znaků. Na výstupu bude ten samý řetězec, ale zrcadlově převrácený. 2. Navrhneme algoritmus, tzn. si určíme postup. a) b)
c)
Nejprve se zjistíme délku vstupního řetězce, abychom věděli, jak dlouhý bude výstupní řetězec Pokud známe délku vstupního a výstupního řetězce, potom máme vyhráno a nyní již stačí pouze vzít poslední znak z původního řetězce a umístit ho jako první znak řetězce nového. A toto nám právě umožňují indexy. Nakonec už jen vypíšeme výstupní řetězec, který je oproti vstupu zrcadlově převrácený
Řetězec znaků - program • Postup : 3. Délka vstupního řetězce – využijeme funkce LENGHT (=anglicky délka), výsledkem této funkce je číslo. Začátek kódu bude vypadat takto: var
delka, poradi : integer; vstupni, vystupni: string; Begin writeln (‘Zadej vstupni retezec (max 255 zna ku): ‘); readln(vstupni); delka := length(vstupni);
Řetězec znaků - program 4. Převrácení řetězce - využijeme toho, že známe délku řetězce, a tudíž víme, kolik znaků musíme přehodit z „konce na začátek“. K tomu nám poslouží cyklus se známým počtem opakování (cyklus FOR). Posledním krokem je vypsání řetězce vystupni for poradi:=1 to delka do begin vystupni[poradi] := vstupni[delka – poradi + 1]; vystupni := CONCAT (vystupni, vystupni[poradi]); {vystupni := vystupni + vystupni[poradi];} end; Writeln (vystupni);
Řetězec znaků - program • Zastavme se u „zmateného“ indexu v prvním přiřazovacím příkazu vlevo je sice index poradi, to bychom ještě pochopili, přece jen musíme projít celý řetězec, a proměnná poradi je i v hlavičce cyklu FOR, ale na pravé straně máme najednou index [delka-poradi+1]. Je to pořadí znaku, který je zrcadlově převrácený ke znaku s indexem poradi. Ukážeme si to například na slově JELEN. Na konci by nám mělo vyjít slovo NELEJ. Délka obou řetězců je 5. poradi = 1 : Vystupni[1] := Vstupni[5 – 1 + 1] Vystupni[1] := Vstupni[5] poradi = 2 : Vystupni[2] := Vstupni[5 – 2 + 1] Vystupni[2] := Vstupni[4] poradi = 3 : Vystupni[3] := Vstupni[5 – 3 + 1] Vystupni[3] := Vstupni[3] poradi = 4 : Vystupni[4] := Vstupni[5 – 4 + 1] Vystupni[4] := Vstupni[2] poradi = 5 : Vystupni[5] := Vstupni[5 – 5 + 1] Vystupni[5] := Vstupni[1]
Řetězec znaků - program Program prevraceni; var delka, poradi : integer; vstupni, vystupni: string; Begin writeln (‘Zadej vstupni retezec (maximalne 255 znaku):‘); readln (vstupni); delka := length(vstupni); for poradi :=1 to delka do begin vystupni:= CONCAT(vystupni, vstupni[delka - poradi + 1]); end; writeln (‘Prevraceny retezec: ‘, vystupni); readln ; end. Úkol: Upravte předcházející program tak, aby testoval, zda je vstupní řetězec PALINDROM
Řetězec znaků PALINDROM Abychom zjistili, zda je dané slovo palindromem, stačí v předcházejícím programu dopsat podmínku, která by testovala, jestli vstupní a výstupní řetězec je stejný. IF vstupni = vystupni THEN WRITELN (‘Je to palindrom‘) ELSE WRITELN (‘Neni to palindrom‘);
Řetězec znaků Pokud bychom zjišťovali, zda je palindromem celá věta (např.: JELENOVI PIVO NELEJ), tak nám náš program v této podobě oznámí, že se o palindrom nejedná, neboť po převrácení bude výsledek JELEN OVIP IVONELEJ . Proto potřebujeme ze vstupního řetězce odstranit mezery. Můžeme toho dosáhnout například tím, že budeme v řetězci procházet znak po znaku, a pokud narazíme na mezeru, tak ji vynecháme. Vstup_original := vstupni ; Vstupni := ‘‘; FOR i:=1 to length(vstup_original) DO Begin IF vstup_original[i] <> ‘ ‘ THEN Vstupni := vstupni + vstup_original[i]; End; Writeln (vstupni);
Zdroje: TurboPascal 6.0 - příručka uživatele (help) Literatura: Radek HYLMAR: Programování pro úplné začátečníky, Computer Press, Brno, 2009, ISBN 978-80-251-2129-0 Januš DRÓZD, Rudolf KRYL: Začínáme s programováním, GRADA a.s., Praha, 1992, ISBN 80-85424-41-X Tomáš HRUŠKA: Pascal pro začátečníky, SNTL, Praha 1989, ISBN 80-03-00345-8 Materiál je určen k bezplatnému používání pro potřeby výuky a vzdělávání na všech typech škol a školských zařízení. Autorem materiálu a všech jeho částí, není-li uvedeno jinak, je : Jaromír Železný Pokud není uvedeno jinak, byly při tvorbě použity volně přístupné internetové zdroje. Autor souhlasí se sdílením vytvořených materiálů a jejich umístěním na www.ssstavji.cz.