380 likes | 521 Views
Програмиране на Пролог. доц. Светла Бойчева Факултет по математика и информатика СУ “Св. Климент Охридски”. Работа с низове. част 6. name( String , List) 'Hello Wolrd!' "Hello Wolrd!" ?- name('Hello',X). X = [72, 101, 108, 108, 111] ; ?- name(X,[104,105]). X = hi
E N D
Програмиране на Пролог доц. Светла Бойчева Факултет по математика и информатика СУ “Св. Климент Охридски”
Работа с низове част 6
name( String , List) • 'Hello Wolrd!' • "Hello Wolrd!" ?- name('Hello',X). X = [72, 101, 108, 108, 111] ; ?- name(X,[104,105]). X = hi ?- name(X,"Hello"). X = 'Hello'
Проверка дали даден символ L е буква letter1(L):- name(L,[X]), name('Z',[Code_Z]), name('A',[Code_A]), X =< Code_Z, X >= Code_A,!. letter1(L):- name(L,[X]), name(a,[Code_a]), name(z,[Code_z]), X =< Code_z, X >= Code_a.
Проверка дали даден символ S е цифра digit1(S):- name(S,[X]), name(0,[Code_zero]), name(9,[Code_nine]), X =< Code_nine, X >= Code_zero.
Проверка дали даден низ е дума is_word(X):- name(X,LX), check_word(LX). check_word([]). check_word([S|Rest]):- letter(S),!, check_word(Rest).
letter(X):- name('Z',[Code_Z]), name('A',[Code_A]), X =< Code_Z, X >= Code_A,!. letter(X):- name(a,[Code_a]), name(z,[Code_z]), X =< Code_z, X >= Code_a.
Проверка дали даден низ е число is_number(X):- name(X,LX), check_number(LX). check_number ([]). check_number ([S|Rest]):- digit(S),!, check_number(Rest).
Проверка дали даден символ X е код на цифра digit(X):- name(0,[Code_zero]), name(9,[Code_nine]), X =< Code_nine, X >= Code_zero.
?- number(1111). Yes ?- integer(1111). Yes ?- atom(a). Yes % string('Hello').
Проверка далидаден символ Symbol принадлежи на даден низ String member_string(Symbol,String):- name(Symbol,[CodeS]), name(String,ListS), member(CodeS,ListS).
Слепване на два дадени низа S1 и S2 append_strings(S1, S2, Result):- name(S1,L1), name(S2,L2), append(L1,L2,L), name(Result,L).
Преобразуване на всички букви в String в главни to_upper(String,Caps):- name(String,LS), name(a,[Code_a]), name(z,[Code_z]), name('A',[Code_A]), transform_up(LS,LC,Code_a,Code_z,Code_A), name(Caps,LC). transform_up([],[],_,_,_). transform_up([X|LS],[Y|LC],Code_a,Code_z,Code_A):- X =< Code_z, X >= Code_a,!, Y is X + Code_A - Code_a, transform_up(LS,LC,Code_a,Code_z,Code_A). transform_up([X|LS],[X|LC],Code_a,Code_z,Code_A):- transform_up(LS,LC,Code_a,Code_z,Code_A).
Преобразуване на всички букви в String в малки to_lower(String,Caps):- name(String,LS), name(a,[Code_a]), name('Z',[Code_Z]), name('A',[Code_A]), transform_down(LS,LC,Code_a,Code_Z,Code_A), name(Caps,LC). transform_down([],[],_,_,_). transform_down([X|LS],[Y|LC],Code_a,Code_Z,Code_A):- X =< Code_Z, X >= Code_A,!, Y is X + Code_a - Code_A, transform_down(LS,LC,Code_a,Code_Z,Code_A). transform_down([X|LS],[X|LC],Code_a,Code_Z,Code_A):- transform_down(LS,LC,Code_a,Code_Z,Code_A).
Проверка дали даден низ A е подниз на даден низ B, т.е. дали А се съдържа в В sub_string(A,B):- name(A,LA), name(B,LB), include(LA,LB). overlap([],_). overlap([X|L1],[X|L2]):- overlap(L1,L2). include(L1,L2):- overlap(L1,L2),!. include(L1,[_|L2]):- include(L1,L2).
Отделяне на списък с думите, които се съдържат в низ tag_words(String,WordsList):- name(String,LS), get_words(LS,WordsList). get_words([],[]). get_words([X|LS],[Word|Result]):- letter(X),!, next_word([X|LS],LW,Rest), name(Word,LW), get_words(Rest,Result). get_words([X|LS],Result):- get_words(LS,Result). next_word([X|L],[X|Res],Rest):- letter(X),!, next_word(L,Res,Rest). next_word(L,[],L).
Проверка дали дадена дума Word се съдържа в даден низ String member_word(Word,String):- to_lower(String,LS), to_lower(Word,LW), tag_words(LS,WordsList), member(LW,WordsList).
Намиране на броя N на срещанията на дадена дума Word в даден низ String count_word(Word,String,N):- to_lower(String,LS), to_lower(Word,LW), tag_words(LS,WordsList), count(LW,WordsList,N). count(X,[],0). count(X,[X|L],K):- !, count(X,L,M), K is M+1. count(X,[_|L],K):- count(X,L,K).
Да се напише предикат, който намира най-дългата (най-късата) дума в низ • Да се напише предикат, който намира всички N буквени думи в низ при зададено число N. • Да се напише предикат, който определя дали всички букви на дадена дума са различни
% задача 1 word_length(Word,N):- name(Word,CW), length(CW,N). min_words(String, MinWord):- tag_words(String,WordsList), min1(WordsList,MinWord). min1([W],W). min1([First|Rest], MinWord):- min1(Rest,MinTemp), word_length(First, N), word_length(MinTemp, K), ( N > K, !, MinWord = MinTemp; MinWord = First ).
% задача 2 word_length(Word,N):- name(Word,CW), length(CW,N). find_words(String,N, List_N):- tag_words(String,WordsList), find1(WordsList,N, List_N). find1([],_,[]). find1([W|Rest],N, Result):- find1(Rest,N, Temp), word_length(W,K), ( N = K, !, Result = [W|Temp] ; Result = Temp).
% задача 3 different_letter(Word):- name(Word,CW), set(CW). % от предната лекция set([]). set([X|L]):- \+ member(X,L), set(L).
Задачи • Даден е низ. Да се напише предикат, който да заменя всички срещания на даден символ с друг даден символ.
replace_all(String,Old,New,Result):- name(String, LS), name(Old, [LOld]), name(New, [LNew]), replace1(LS, LOld,LNew, LRes), name(Result,LRes). replace1([],_,_,[]). replace1([LOld|Rest],LOld,LNew,[LNew|Res]):- !,replace1(Rest,LOld,LNew,Res). replace1([X|Rest],LOld,LNew,[X|Res]):- replace1(Rest,LOld,LNew,Res).
Задачи • Даден е низ. Да се напише предикат, който да заменя всички срещания на дадена дума с друга дадена дума.
% от предната лекция swap1(List,Old,New,Res):- append(Prev,Temp,List), append(Old,Next,Temp), swap1(Prev,Old,New,Res1), swap1(Next,Old,New,Res2), append(Res1,New,T1), append(T1,Res2,Res). swap1(List,_,_,List).
replace_words(String,OldWord,NewWord,Result):- name(String,List), name(OldWord,Old), name(NewWord,New), swap1(List,Old,New,Res), name(Result,Res).
Задачи • Даден е низ, който съдържа текст. Да се напише предикат, който заменя всяка дума от текса с обърнатата й дума, т.е. буквите от думата да са изписани в обратен ред.
reverse_text(String,Result):- name(String, LS), rev1(LS,Res), name(Result,Res). next_word([X|L],[X|Res],Rest):- letter(X),!, next_word(L,Res,Rest). next_word(L,[],L). rev1([],[]). rev1([X|L], Result):- letter(X),!, next_word([X|L], LW, Rest), reverse(LW, RevLW), % вграден rev1(Rest, Temp), append(RevLW,Temp,Result). rev1([X|L],`[X|Result]):- rev1(L, Result).
Задача Да се напише предикат c който по зададен списък от думиWordsList и шаблон Template намира всички думи от списъка, които съответстват на дадения шаблон. Шаблонът може да съдържа букви (a..z), ? (замества точно 1 буква)и * (замества 0 или повече букви). Пример: ?-match(['love','like','late','low','lion','lie'], 'l??e',R). R=['love','like','late'] ?-match(['love','like','late','low','lion','lie'], 'l*',R). R =['love','like','late','low','lion','lie '] ?-match(['love','like','late','low','lion','lie'], '*e',R). R =['love','like','late','lie ']
match([],_,[]). match([W|Rest],Template,[W|Res]):- match_word(W,Template),!, match(Rest, Template,Res). match([_|Rest],Template,Res):- match(Rest,Template,Res). match_word(Word,Template):- name(Word,W), name(Template,T), match_code(W,T).
match_code([],[]). match_code([X|W],[X|T]):- letter(X),!, match_code(W,T). match_code([_|W],[Code|T]):- name('?',[Code]), match_code(W,T). match_code(W,[Code|T]):- name('*',[Code]), match_code(W,T). match_code([_|W],[Code|T]):- name('*',[Code]), match_code(W,[Code|T]).
Задачи • Даден е низ, който съдържа непрекъсната последователност от цифри. Дадено е кодиране (списък от дойки елементи – буква / число), при което на всяка букава (a..z и на символа интервал) е съпоставено различно естествено двуцифрено число. Да се напише предикат, който по зададен низ и кодиране да връща декодирания низ.
text1('25672525192756218752141219641897'). code1([ a/33, b/45, c/56, d/67, e/25, f/27, g/21, h/12, i/64, j/88, k/39, l/90, m/87, n/18, o/11, p/99, q/55, r/81, s/52, t/97, u/10, w/30, x/44, y/41, z/14, ' '/19]).
get_next([X,Y|Rest],Code,Rest):- name(D1,[X]), name(D2,[Y]), Code is D1*10+D2. decode(CText,Encoding,DText):- name(CText,ListCodes), find_codes(ListCodes,Encoding,LL), name(DText,LL). find_codes([],_,[]). find_codes(Codes,Encoding,[AL|List]):- get_next(Codes,C,Rest), member( L/C,Encoding), name(L,[AL]), find_codes(Rest,Encoding,List).
Задачa за самостоятелна работа • Даден е низ, който съдържа букви (a..z, A..Z) и специални знаци (интервали и препинателни знаци). Дадено е кодиране (списък от дойки елементи – буква / число), при което на всяка букава е съпоставено различно естествено число. Да се напише предикат, който по зададен низ и кодиране да връща прекодирания низ. Специалните символи в дадения низ да остават непроменени и в резултатния.
text1('This is an example.'). code1([ a/33, b/45, c/56, d/67, e/25, f/27, g/21, h/12, i/64, j/88, k/39, l/90, m/87, n/18, o/11, p/99, q/55, r/81, s/52, t/97, u/10, w/30, x/44, y/41, z/14]).
code(CodeText,Encoding,NormalText):- name(NormalText,LL), find_codes(ListCodes,Encoding,LL), name(CodeText,ListCodes). find_codes([],_,[]). find_codes(Result, Encoding,[Old|List]):- change(Old,Encoding,New), find_codes(Codes,Encoding,List), append(New,Codes,Result). change(Old,Encoding,New):- letter(Old),!, name(L,[Old]), member( L/Code, Encoding), name(Code,New). change(Old,Encoding,[Old]).