Wprowadzenie
Powiemy, że znak X
występuje w kontekście napisu S
, jeśli S
bezpośrednio poprzedza X
. Np. w tekście:
ALA_MA_KOTA_ALE_NIE_MA_MYSZY
w kontekście napisu A_
występują znaki M
, K
i A
, w kontekście AL
występują znaki A
oraz E
, w kontekście OT
jest tylko znak A
, a w kontekście
ZY
nie występuje żaden znak.
Polecenie
Napisz program, który wywołany poleceniem:
gdzie K
i N
to nieujemne liczby całkowite, wczyta z wejścia tekst i wypisze na wyjście K
jego początkowych znaków. Każdy następny wypisany znak wybierzemy losowo spośród znaków, które w tekście wejściowym wystąpiły w kontekście K
ostatnio wypisanych
znaków. Prace należy zakończyć po wypisaniu N
znaków, a także w przypadku, gdyby w kontekście ostatnio wypisanych znaków w tekście wejściowym nie było żadnego znaku.
Jeśli na wejściu jest mniej niż K
znaków, program ma tylko skopiować tekst wejściowy na wyjście.
Przykłady
Program uruchomiony poleceniem:
po wczytaniu z wejścia tekstu:
ALA_MA_KOTA_ALE_NIE_MA_MYSZY
może wypisać na wyjście np.:
ALE_MA_KOTALALE_NIE_NIE_ALE_NIE_ALE_A_ALE_A_NIE_MY
Program uruchomiony poleceniem:
./wp08lab_zad3 0 200 <wp08lab_zad1.txt
gdzie wp08lab_zad1.txt jest treścia pierwszego zadania zaliczeniowego, może wypisać:
WwPpeBxyt}oATuxprsspJZZ.g""|pijNyTZT1tS-Iaw{Pchdd ywt<W
WjldpCwA}iBrzgityCPt|b"xZTmPrw<|ce1G
C.kaeGuh}u<iT}J1pGwy|"
ltjg|x"NNxBy
TGkugmNrGhIy<1kh.y|nZkdlJNbrzIpIypWIW:.pS
AJBeAso}}hytatx ."e,hs G-kot
Program uruchomiony poleceniem:
./wp08lab_zad3 1 200 <wp08lab_zad1.txt
może wypisać:
Wserzwnioleprelico,zc kcz}", ksabiespusami:
g
Inciczw. sich:
semo,},T ie:
Pomakamu. wnt,A>|CCCC},Sbelubeg
GraSym ->},{B>Blu. uzakodywilnnilowypo.
Inkaw,bS->,zy}"{"wi:
Na,blicedejdozpicicna
Zaci tu, la
Program uruchomiony poleceniem:
./wp08lab_zad3 2 200 <wp08lab_zad1.txt
może wypisać:
Wsty wy stu pow.
S - zapis z
pram, lu, grawnyc matow.
S - niczapisementych, lu "w" tory zami "|". W symi, a do slicz
tyklady cwiej jeslitekstrogramaty,z},A>
Zakamy,S->w", cwielonegolnosty, od z sach.
Program uruchomiony poleceniem:
./wp08lab_zad3 3 200 <wp08lab_zad1.txt
może wypisać:
Wstepuja wykladane pusty, rozdzi, elementy znaczego by danych znakiemy zadnych
T - zapisz tekstowa pusty, ciag
znajdujemy symbol pomocniczego. Slowo przykladane danie "A" to ma
wypisywaliczenty ciag p
Program uruchomiony poleceniem:
./wp08lab_zad3 4 200 <wp08lab_zad1.txt
może wypisać:
Wstep do produkcja.
Przyjmujemy, byc moze puste jest, programatyki bezkontekstu z
poprawdzi, czy znakiem "}". Pomiedzy tymi
znakow, oprocz
tych strona produkcji postaci "A->w", gdzie "A" to symbol po
Program uruchomiony poleceniem:
./wp08lab_zad3 5 200 <wp08lab_zad1.txt
może wypisać:
Wstep do program, ktory sprawdzi, czy na wejsciu znajduje sie wiersz tekstu z
poprawne dane
w przecinkami, elementy zbioru symboli konczy znaku "{" a koncowych
P - zapisem gramatyki bezkontekstowej.
Uwagi
-
Na podstawie tekstu z wejścia należy zbudować strukturę danych przechowującą, dla każdego kontekstu długości K, znaki, które w tym kontekście wystąpiły.
-
Najprostszym rozwiązaniem byłoby posłużenie się listą kontekstów, z każdym z nich wiażąc listę znaków występujących w tym kontekście. Koszt wyszukiwania kontekstu będzie w tym przypadku duży. By go zmniejszyć, można sięgnąć po strukturę danych pozwalającą na bardziej efektywne wyszukiwanie, np. drzewo lub graf. Wybór struktury danych będzie miał wpływ na ocenę programu.
-
Można założyć, że wartość K, przekazana jako pierwszy argument programu, nie jest bardzo duża, ale nie należy nakładać na nią sztucznych ograniczeń. Nie należy też ograniczać długości tekstu wejściowego ani wartości drugiego argumentu programu (N).
-
W tym zadaniu ignorujemy podział tekstu wejściowego na wiersze. Zakładamy, że dane dla programu to ciąg znaków, które będziemy wczytywali operacją
read()
. Obecność danych na wejściu będziemy sprawdzali bezargumentową funkcją eof()
.
-
Do rozwiązania zadania będzie potrzebna procedura
val()
oraz funkcje paramCount()
, paramStr()
. Ich użycie demonstruje program (razy.pas):
program razy;
var i1, i2 : Integer;
w : Word;
procedure blad(s : String);
begin
writeln(s);
halt
end;
begin
if paramCount <> 2 then
blad('Program oczekuje dwoch argumentow');
val(paramStr(1), i1, w);
if w <> 0 then
blad('Pierwszy argument niepoprawny');
val(paramStr(2), i2, w);
if w <> 0 then
blad('Drugi argument niepoprawny');
writeln(i1 * i2)
end.
-
Zastosowany tu mechanizm generowania ciągów znaków nazywamy łańcuchem Markowa.