Rešenja ili njihove skice
Opis postupka: Ograničenost intervala u kome su predstavljeni brojevi tipa
integer ne omogućava da računamo sa velikim celim brojevima.
Rešenje se, tada, traži tako što se broj n predstavi kao
niz cifara nk, ... , n0 u sistemu sa osnovom
b:
n = nk * bk + ...
+ n1 * b1 + n0 * b0
Tada je neophodno napisati programe koji izvršavaju pojedine
aritmetičke operacije nad ovakvom reprezentacijom broja.
Za osnovu se obično bira b = 10, ali je osnovni kriterijum
da se aritmetičke operacije što lakše implementiraju.
Veliki broj se predstavlja pomoću niza čiji su
elementi cifre tog broja. Na taj način se problem izračunavanja
velikog broja prevodi na rad sa malim brojevima (koji su u opsegu
tipa integer.
Rešenje:
program faktorijel;
const m = 100; mc = 100; max = 50;
var fakt: array[ 1 .. mc ] of integer;
n, d, prenos, i, p: integer;
procedure ispis;
var i, k: integer;
begin
write(n : 3,"! = ", fakt[ d ] : 1 );
for i := d + 1 to mc do
begin
k := m;
while k > 1 do
begin
k := k div 10;
write( fakt[ i ] div k mod 10 : 1 );
end
end;
writeln
end {ispis};
begin
fakt[ mc ] := 1; d := mc; n := 0;
ispis;
for n := 1 to max do
begin
prenos := 0;
for i := dm downto d do
begin
p := fakt[ i ] * n + prenos;
f[ i ] := p mod m;
prenos := p div m;
end
if prenos > 0 then
begin
d := d - 1;
fakt[ d ] := prenos
end;
ispis;
end
end.
Skica rešenja: Sugerirano rešenje potiče od
Džona Bentlija (Bentley, John: Programming Pearls, Addison-Wesley,
1986; pp. 19 - 21). Originalno Bentlijevo rešenje, pod UNIX-om,
koristi sledeči "pipeline" nad ulaznim tekstom:
SIGN <tekst.txt | SORT | SQUASH >izlaz
Funkcija SIGN
odgovara koraku 2.2 u zadatku, a
implementirana je kao funkcija u C-u koja
koristi QUICKSORT
:
#define WORDMAX 101
main()
{ char thisword[ WORDMAX ], sig[ WORDMAX ];
while( scanf("%s", thisword ) != EOF ) {
strcpy( sig, thisword );
qsort( sig, strlen( sig ), 1, compchar );
printf("%s %s\n", sig, thisword);
}
}
Ovaj program čita sa ulaza reč thisword, maksimalne
dužine MAXWORD
, i prepisuje je u nisku sig.
Niska sig se sortira prema poretku definisanom funkcijom
compchar (u zadatku 2. to je poredak indukovan
ASCII
-kolacionom sekvencijom). Rezultat sortiranja se
prenosi na izlaz preko funkcije printf u obliku
para (kanonski oblik reči, reč) (na primer,
(aartv, vatra).
Izlaz iz prethodnog koraka se u Bentlijevom rešenju prosleđuje
u program za eksterno sortiranje SORT
. U zadatku je
ovaj korak pojednostavljen tako što se iz ulazne datoteke izdavaju
samo reči određene dužine m kojih ima najviše 200. Umesto
eksternog sortiranja dovoljno je koristiti strukturu
niza (array).
Funkcija SQUASH
odgovara koraku 2.4:
kako je rezultat prethodnog koraka niz dvodimenzionali niz
sortiran po prvoj koloni (koja sadrži kanonske oblike),
da bi se izdvojili anagrami dovoljno je porediti uzastopne elementa
iz prve kolone. Ova operacija predstavlja jedan red koda u
AWK
-u:
$1 != prev { prev = $1; if ( NR > 1 ) printf "\n" }
{ printf "%s", $2 }
{ printf "\n" }
END
Interpretirani na primeru 2. zadaaka,
ovi redovi znače da se u matrici parova oblika
(kanonski oblik reči, reč), poredi prvi element ($1)
u tekućem redu sa prvim elementom prethodnog reda. Ako su ove niske jednake, onda
je drugi element para ($2) anagram sa drugim elementom iz prethodnog
reda i treba ga ispisati. Ako je pak $1 != prev,
onda se vrši zamena vrednosti u promenljivoj prev.
Na primer, ako je ulazna datoteka sadržavala tekst:
vatra rada trava dana dara vrata nada...
rezultati pojedinih koraka su sledeći:
vatra aartv vatra aand nada
rada aadr rada aand dana
trava aartv trava aard dara dana nada
dana --SIGN
--> aand dana --SORT
--> aard rada --SQUASH
--> dara rada
dara aard dara aartv trava trava vatra vrata
vrata aartv vrata aartv vatra
nada aand nada aartv vrata