如果有一个支点,我如何在prolog中分解列表?

时间:2013-04-01 05:00:56

标签: arrays split prolog infinite-loop break

我正在开展一个小型项目以进行精益求精。我现在要做的是,给出一个句子,返回一个单词列表。所以,我正在接受一个字符数组,例如“高点和低点”,并试图将其分为“高点”和“低点”。我正在使用一个字符数组,因为我想用自己的单词来玩,我认为字符串不适用于此。

这是我的代码。

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).

我遇到的问题是这变成了无限循环。最终它会传递自己的空输入,而我的基本情况写得不够好,无法处理这个问题。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:1)

我认为get_first_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).

试验:

?- split_at("highs and lows", 0' ).
highs
and
lows
true .

答案 1 :(得分:1)

如果使用SWI-Prolog,则值得考虑使用原子来表示句子,单词,单词的部分等。如你所见here,你的问题变成了(如果你的句子是一个原子):

?- atomic_list_concat(Ws, ' ', 'highs and lows').
Ws = [highs, and, lows].

还有一些有用的谓词,例如atom_concat/3(我们可以说原子是append/3),或sub_atom/5可以多种方式使用。

作为旁注,SWI-Prolog对原子长度没有人为限制,实际上建议使用原子而不是字符串或字符代码列表。

答案 2 :(得分:1)

在描述列表时(在这种情况下:字符代码列表,这是你的字符串是什么),也总是考虑使用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.