1

到目前为止,我能想到的最好的事情是这个功能:

 numberFromList([X], X) :-  
    digit(X), !.  
 numberFromList(List, N) :-  
    member(X, List),     
    delete(List, X, LX),  
    numberFromList(LX, NX),  
    N is NX * 10 + X.

wheredigit/1是一个验证原子是否为十进制数字的函数。

numberFromList(List, N)查找可以由 中的所有数字组成的所有数字List
例如[2, 3] -> 23, 32。但我想得到这个结果:[2, 3] -> 2, 3, 23, 32

我花了很多时间思考这个问题,我怀疑你可能会append(L, _, List)在某个时候使用类似的东西来获取长度较短的列表。

我将不胜感激任何贡献。

4

3 回答 3

0

谓词unique/3生成所有长度不超过MaxLen由符号组成的列表SymbolsL生成的列表一次存储在 中。

unique(MaxLen, Symbols, L) :-
    between(0, MaxLen, Len),
    length(L, Len),
    unique(Symbols, L).

用于生成列表的辅助谓词。

unique(_, []).
unique(Set, [H|R]) :-
    select(H, Set, ReducedSet),
    unique(ReducedSet, R).

演示上述谓词的简单程序:

main :-
    unique(5, [2,3], L),
    write(L), nl, fail.
于 2010-05-26T23:19:31.010 回答
0

这是一种方法,将 SWI-PROLOG 内置用于atomic_list_concat/2,atom_number/2select/3. 首先,入口点是指使用初始为空的累加器的实现:

numberFromList(L, N) :-
    numberFromList(L, [], N).

谓词numberFromList/3要么从列表中累积数字(未经检查),要么不累积,留下选择点:

numberFromList([_|Cs], Acc, N) :-
    numberFromList(Cs, Acc, N).
numberFromList([C|Cs], Acc, N) :-
    numberFromList(Cs, [C|Acc], N).

的最后一个子句numberFromList/3置换累积的数字列表并将它们连接成一个原子,然后根据需要将其转换为数字:

numberFromList([], [C|Cs], N) :-
    permute([C|Cs], PermutedAcc),
    atomic_list_concat(PermutedAcc, AN),
    atom_number(AN, N).

有时permute/2(如下面手动定义的)可能会以内置形式提供,例如permutation/2. 这是使用的手动定义select/3

permute([], []).
permute([E|Es], [E0|PL]) :-
    select(E0, [E|Es], Rem),  
    permute(Rem, PL).

如果您想要所有结果的列表并且不想numberFromList/2回溯自身,则可以将调用包装到调用中numberFromList/3(在 的第一个子句中使用空累加器numberFromList/2findall/3

于 2010-05-27T01:40:10.897 回答
0

当您从列表中跳过数字时,您会丢失大小写。

 numberFromList([X], X) :-  
    digit(X), !.  
 numberFromList(List, N) :-
    member(X, List),     
    delete(List, X, LX),
    numberFromList(LX, NX),  
    ( % use X
        N is NX * 10 + X
    ; % skip X
        N = NX
    ).

顺便说一句,正如@Roland Illig 提到的那样,select(X, List, LX)要替换member(X, List), delete(List, X, LX)

于 2010-05-27T04:27:28.970 回答