Arrays 给定一个轴,我如何在prolog中分解列表?
我正在做一个小项目来精简prolog。我现在想做的是,给定一个句子,返回一个单词列表。所以,我在接受一个字符数组,例如“high和low”,并试图将其分为“high”和“low”。我使用字符数组是因为我想处理单词本身,而我认为字符串不适合这样做 这是我的密码Arrays 给定一个轴,我如何在prolog中分解列表?,arrays,split,prolog,infinite-loop,break,Arrays,Split,Prolog,Infinite Loop,Break,我正在做一个小项目来精简prolog。我现在想做的是,给定一个句子,返回一个单词列表。所以,我在接受一个字符数组,例如“high和low”,并试图将其分为“high”和“low”。我使用字符数组是因为我想处理单词本身,而我认为字符串不适合这样做 这是我的密码 get_first_word([], _, []):- !. get_first_word(X, Pivot, Input):- append(X, [Pivot|_], Input), !. split_at([],_).
get_first_word([], _, []):-
!.
get_first_word(X, Pivot, Input):-
append(X, [Pivot|_], Input),
!.
split_at([],_).
split_at(Input, Pivot):-
get_first_word(X, Pivot, Input),
writef(X),
append(X, Y, Input),
split_at(Y, Pivot).
我遇到的问题是,这会变成一个无限循环。最终,它会将自己传递为空输入,而我的基本案例编写得不够好,无法处理这个问题。如何解决这个问题?我认为
get\u first\u word
遗漏了一个参数:它应该“返回”单词和其他单词,考虑到Pivot不出现在输入中的可能性
我还移动了参数以遵循传统的“开始时输入,结束时输出”
get_first_word(Input, Pivot, Word, Rest):-
append(Word, [Pivot|Rest], Input), !.
get_first_word(Input, _Pivot, Input, []).
split_at([], _).
split_at(Input, Pivot):-
get_first_word(Input, Pivot, W, Rest),
writef(W),nl,
split_at(Rest, Pivot).
测试:
如果您使用SWI Prolog,则值得考虑使用原子来表示句子、单词、单词的部分等。如您所见,您的问题变成(如果您的句子是原子): 还有更多有用的谓词,例如
atom\u concat/3
(我们可以说它是原子的append/3
),或者sub\u atom/5
,它们可以以多种方式使用
作为旁注,SWIPROlog对原子的长度没有人为限制,实际上建议使用原子而不是字符串或字符代码列表。
当描述列表时(在这种情况下:字符串的字符代码列表),也总是考虑使用DCG。例如:
string_pivot_tokens(Cs, P, Ts) :- phrase(tokens(Cs, P, []), Ts).
tokens([], _, Ts) --> token(Ts).
tokens([C|Cs], P, Ts) -->
( { C == P } -> token(Ts), tokens(Cs, P, [])
; tokens(Cs, P, [C|Ts])
).
token([]) --> [].
token([T|Ts]) --> { reverse([T|Ts], Token) }, [Token].
例如:
?- string_pivot_tokens("highs and lows", 0' , Ts), maplist(atom_codes, As, Ts).
Ts = [[104, 105, 103, 104, 115], [97, 110, 100], [108, 111, 119, 115]],
As = [highs, and, lows] ;
false.
在您计划使用SWI Prolog的情况下,您可能希望使用原子来表示单词和句子。然后,您可以使用内置函数来分析和构造atoms(),例如
atomic\u list\u concat/3
,它基本上完全符合您对atoms的描述。我正在尝试制作一个简单的翻译脚本,我需要大量使用单个单词和单词部分。我能用SWIProlog“组装”字符串吗?
string_pivot_tokens(Cs, P, Ts) :- phrase(tokens(Cs, P, []), Ts).
tokens([], _, Ts) --> token(Ts).
tokens([C|Cs], P, Ts) -->
( { C == P } -> token(Ts), tokens(Cs, P, [])
; tokens(Cs, P, [C|Ts])
).
token([]) --> [].
token([T|Ts]) --> { reverse([T|Ts], Token) }, [Token].
?- string_pivot_tokens("highs and lows", 0' , Ts), maplist(atom_codes, As, Ts).
Ts = [[104, 105, 103, 104, 115], [97, 110, 100], [108, 111, 119, 115]],
As = [highs, and, lows] ;
false.