问题
I have a list of characters (basically a word) and I want to substitute the vowels in the word by underscore ['_'] and return a new list. eg:
?-sub([s,e,g,e,d],A).
A=[s,_,g,_,d]
My attempt built the new list in the reverse order then finally when it exited from the predicate call it dismantle everything and declare that it found the goal without the output string!
The algorithm I used is: pick element of a list and check whether it is a vowel or not and append the ['_'] or the element itself to the new list.
sub([],B).
sub([X|T1],Y):-
((vocal(X), append(['_'],Y,Z));
(not(vocal(X)), append([X],Y,Z))),
sub(T1,Z).
vocal(a).
vocal(e).
vocal(i).
vocal(o).
vocal(u).
回答1:
In SWI-Prolog:
sub(In, Out) :-
maplist(vowel_to_underscore, In, Out).
vowel_to_underscore(Vowel, '_') :-
vocal(Vowel),
!.
vowel_to_underscore(X, X).
vocal(a).
vocal(e).
vocal(i).
vocal(o).
vocal(u).
回答2:
The first thing you should do: pay attention to the warnings. Surely the compiler warned you about the singleton in the base case of the recursion.
sub([], []).
sub([X|Xs], [Y|Ys]) :-
(vocal(X), '_' = Y ; X = Y),
!, sub(Xs, Ys).
Please note that in Prolog the = doesn't means assign, but unification. You should understand this and (if you really want to understand Prolog) why your solution reverses the input. Try to write reverse/2 by yoursef!
来源:https://stackoverflow.com/questions/7542406/how-do-i-replace-vowels-in-a-list-with-underscore