【问题标题】:Prolog: find all numbers of unique digits that can be formed from a list of digitsProlog:查找可以从数字列表中形成的所有唯一数字
【发布时间】:2010-05-26 22:08:43
【问题描述】:

到目前为止我能想到的最好的东西就是这个功能:

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

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

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

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

我将不胜感激。

【问题讨论】:

  • 你想要怎样的数字?在一个列表中还是在回溯时一次一个?

标签: list numbers prolog digits


【解决方案1】:

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

 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)

【讨论】:

    【解决方案2】:

    谓词unique/3 生成长度不超过MaxLen 的所有列表,其中包含来自Symbols 的符号。生成的列表存储在L,一次一次。

    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.
    

    【讨论】:

      【解决方案3】:

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

      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/2 的第一个子句中使用空累加器)包装在 @ 987654326@电话。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-15
        • 1970-01-01
        • 1970-01-01
        • 2018-02-22
        • 1970-01-01
        相关资源
        最近更新 更多