Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
954 views
in Technique[技术] by (71.8m points)

recursion - Prolog: Split list at integer in list of lists

I would like to split a list of words separated through integers into a list of lists.

Sample query and expected result:

?- separatewords([h,e,l,l,o,1,o,v,e,r,3,t,h,e,r,e], X).
X = [[h,e,l,l,o],[o,v,e,r],[t,h,e,r,e]].

The following things I already achieved: Splitting the list into one list before the first integer and one after the first integer:

Sample query with result:

?- take1word([h,e,l,l,o,1,o,v,e,r,3,t,h,e,r,e], X, Y).
X = [h,e,l,l,o], Y = [o,v,e,r,3,t,h,e,r,e].                 % OK

My code:

 take1word([H|T],[],T) :-
    integer(H).
 take1word([H|T],[H|Hs],Y) :-
    (  float(H), take1word(T,Hs,Y)
    ;  atom(H), take1word(T,Hs,Y)
    ).

For separating words my code is the following:

 separatewords([],[]).
 separatewords([H|T],L) :-  separatewords(T,[take1word([H|T],)|L]).

It only give me false as a result, but I don't know, what I am doing wrong.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You have an issue with take1word/3: it will take a word if there is an integer in the list, but it will not take the last word. You need to add another base clause to it:

take1word([], [], []).
take1word([H|T],[],T) :- integer(H).
take1word([H|T],[H|Hs],Y) :- float(H), take1word(T,Hs,Y); atom(H), take1word(T,Hs,Y).

Now your separatewords/2 will work:

separatewords([],[]).
separatewords(L, [W|T]) :- take1word(L,W,R), separatewords(R,T).

Demo.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...