[[programovani-i|Programování I - cvičení]]
====== 3. cvičení - 16.10.2009 ======
===== Co jsme dělali? =====
==== Ukázky různé složitosti algoritmů ====
=== Umocňování čísla na velký exponent ===
program power;
{ Exponentiate a base to an exponent: base^exp }
{ Compute base^exp in O(n) time by simple multiplication. }
function power_linear_time(base, exp : integer) : integer;
var
product : integer; {base i-times multiplied with itself = base^i}
i : integer;
begin
product := 1;
for i := 0 to exp - 1 do
product := product * base;
power_linear_time := product
end;
{
Compute base^exp in O(log_2(n)) time.
The exponent is
Intermediate powers are utilized
}
function power_log_time(base, exp : integer) : integer;
var
product : integer;
tmp_power : integer; {intermediate power}
i : integer;
begin
tmp_power := base;
product := 1;
i := exp;
while (i > 0) do
begin
if ((i mod 2) = 1) then
begin
product := product * tmp_power
end;
tmp_power := tmp_power * tmp_power;
i := i div 2
end;
power_log_time := product
end;
var
base, exp : integer;
begin
readln(base, exp);
writeln('exp O(n): ', base, '^', exp, ' = ', power_linear_time(base, exp));
writeln('exp O(log(n)): ', base, '^', exp, ' = ', power_log_time(base, exp));
end.
=== Testování, jestli číslo je mocninou dvojky ===
Je-li číslo N mocninou dvojky, má v binárním zápisu jedničku a pak samé nuly. N-1 má binárním zápisu samé jedničky. Tedy bitový součin (N AND (N - 1)) je roven nule. To lze použít k efektivnímu testu v čase O(1).
Příklad:
N = 32
100000 = 32
AND 011111 = 31
---------------
= 000000 = 0
N = 91
1011010 = 90
AND 1011001 = 89
----------------
= 1011000 = 88 != 0
function isPowerOfTwo(n:integer) : boolean;
begin
isPowerOfTwo := (n AND (n - 1)) = 0
end;
Méně efektivním řešením by bylo například v cyklu dělit číslo dvojkou a koukat se, jestli někde nedostaneme jako zbytek jedničku. To nám ale zabere čas O(log(B)), kde B je počet bitů čísla.
function isPowerOfTwo(n:integer) : boolean;
begin
while (n > 0) do
begin
if ((n mod 2) = 1) then
begin
isPowerOfTwo := false;
exit
end;
n := n div 2
end;
isPowerOfTwo := true
end;
==== Práce s textovými řetězci a se znaky ====
=== Otočení textového řetězce (vypsání pozpátku) ===
Načteme textový řetězec a chceme ho vypsat v opačném pořadí znaků.
program reverse_string;
var
s : string;
i, n : integer;
begin
readln(s);
n := length(s);
for i:=1 to n do
begin
write(s[n-i+1]);
end;
writeln
end.
* Zkuste si toto naimplementovat jako funkci ''function reverse(text : string) : string);''.
* Zkuste si naimplementovat proceduru ''procedure reverse_array(var arr : array of integer));'', která otočí pole.
=== Zkuste si ===
Zkuste si naimplementovat pár jednoduchých funkcí pro práci se znaky a textem. Použijte funkce ''ord'' a ''chr'' (viz nápovědu v Borland Pascalu nebo Google). Využívejte už hotové věci pro tvorbu dalších věcí.
* manipulace se znaky
* napište funkci ''toLower(c : char) : char'', která velká písmena anglické abecedy převede na malá a ostatní znaky nechá být, jak jsou
* napište funkci ''toUpper(c : char) : char'', která malá písmena anglické abecedy převede na velká a ostatní znaky nechá být, jak jsou
* napište funkci ''toLowerStr(text : string) : string'', která převede v textu velká písmena anglické abecedy na malá a ostatní znaky nechá být, jak jsou
* podobně napište symetrickou funkci ''toUpperStr(text : string) : string'', která převede v textu malá písmena anglické abecedy na velká a ostatní znaky nechá být, jak jsou
* predikáty pro znaky
* napište funkci ''isLower(c : char) : boolean'', která zjistí, zda-li znak je malé je písmeno anglické abecedy nebo není
* podobně napište symetrickou ''isUpper(c : char) : boolean''
* napište funkci ''isLetter(c : char) : boolean'', která zjistí, zda-li znak je písmeno anglické abecedy nebo není
* napište funkci ''isDigit(c : char) : boolean'', která zjistí, zda-li znak je číslice nebo není
* napište funkci ''isAlphaNum(c : char) : boolean'', která zjistí, zda-li znak je číslice nebo písmeno anglické abecedy, nebo není nic z toho
* Zkuste rozšírit úlohu [[domaci-ulohy#frekvencni_analyza_textu|frekvenční analýza textu]] tak, aby analyzovala malá i velká písmena a také číslice.
* Zkuste rozšírit úlohu [[domaci-ulohy#frekvencni_analyza_textu|frekvenční analýza textu]] tak, aby analyzovala všechny tisknutelné znaky.
* Zkuste rozšírit úlohu [[domaci-ulohy#frekvencni_analyza_textu|frekvenční analýza textu]] tak, aby analyzovala všechny znaky znakové sady ASCII tak, že budete vypisovat i číslo znaku. Netisknutelné znaky (viz stránku o [[wp>ASCII]] na Wikipedii) nevypisujte.
==== Práce s IDE Borland Pascal ====
=== "Hello world!" ===
program helloworld;
begin
writeln("Hello world!")
end.
* [[http://mff.lokiware.info/KlavesoveZkratky|klávesové zkratky]] k FP/BP.
* Pár slov od dr. Holana, [[http://ksvi.mff.cuni.cz/~topfer/Texty/ide.pdf|jak se IDE Free Pascalu používá]] (je to velice podobné jako u BP).
* IDE = Integrated Development Environment, tj. v rámci jednoho prostředí máte editor kódu, kompilátor, debugger, nápovědu a další funkce
* spuštení, nastavení adresářů (hlavně pracovního)
* práce se soubory - vytvoření, uložení, otevření
* editace zdrojového kódu
* práce s okny
* kompilace, spuštení, pohled na výstup z programu
* spuštění v režimu ladění (pomocí [[wp>Debugger|debuggeru]])
* step over, trace into
* watch, [[wp>Breakpoint|breakpoint]], [[wp>Call_stack|call stack]]
* nápověda - kontextová, index