带列表的Prolog程序

时间:2013-10-20 09:59:44

标签: prolog turbo-prolog

我必须在turbo prolog中解决以下问题:“确定列表中数字表示给定数字的数字的乘积。例如:[1 9 3 5 9 9] * 2 - &gt ; [3 8 7 1 9 8]“。

我解决这个问题的思路是,我首先计算产品,然后将其数字放入列表中。但我真的无法想到这最后一部分。到目前为止,这是我的源代码:

结构域

list=integer*

谓词

    length(list,integer)

powerten(integer,integer)

product(integer,list,integer) /* this predicate computes the product */

    /* the product,powerten and length are taken care of */


addDigit(integer,list) /* this predicate should decompose the number in its digits and put them in the list */


productList(integer,list,list)

条款

     length([],0).

     length([_|T],L):-

            length(T,L1),

            L=L1+1.

powerten(0,1):-!.

powerten(L,N):-
    L1=L-1,
    powerten(L1,N1),
    N=N1*10.

product(_,[],0):-!.

product(NR,[H|T],RESULT ):-
    length([H|T],LEN),
    L2=LEN-1,

    powerten(L2,N),
    product(NR,T,R1),
    RESULT=R1+H*N*NR.




addDigit(0,[]):-!.


addDigit(NR,[NR|_]):-

    NR>0,
    DIGIT = NR MOD 10,
    NR1=NR DIV 10,
    addDigit(NR1,_).        


productList(NR,L1,L2):-

     /* this is the "main" predicate . Its arguments are NR - the first factor, L1- the 
         initial list, whose digits make the second factor, L2 - the result list which            
          contains  the digits of he result */

            product(NR,L1,RESULT),

            addDigit(RESULT,L2).

正如你所看到的,直到addDigit谓词都很好。我只是找不到将产品的数字添加到最终列表的方法。任何人都可以帮我解决问题吗? 感谢。

2 个答案:

答案 0 :(得分:0)

addDigit对我来说似乎不对:你只使用第一个,并且未指定尾部!尝试

addDigit(NR,[DIGIT|Ns]):-
    NR>0,
    DIGIT = NR MOD 10,
    NR1 = NR DIV 10,
    addDigit(NR1, Ns).

答案 1 :(得分:0)

这对我来说似乎很复杂。问题是基本上做长形式的乘法,就像你在纸上做的那样。如果您首先反向列表(使用内置的reverse/2谓词),事情变得更加简单:

%--------------------------------------------------------------%
% Mult/3: multiply a integer, represented as a list of digits, %
%         by an integer value N, producing an integer, also    %
%         represented as a lsit of digits.                     %
%--------------------------------------------------------------%
multiply( Ds , N , Result) :-
  reverse(Ds,Rs) ,
  multiply( Rs , N , 0 , T ) ,
  reverse( T , Result )
  .

%
% the worker predicate that does all the work
%
multiply( [] , _ , C , []      ) :-    % if the list is exhausted
  C =< 0                               %   and the carry is 0,
  .                                    %   we're done. C'est fini.
multiply( [] , _ , C , [C] ) :-        % if the list is exhausted
  C > 0 ,                              %   and the carry is 1-9, then
  C < 10                               %   The last digit in the result is the carry
  .                                    %   We're done. C'est fini.
multiply( [] , _ , C , [R|Rs] ) :-     % If the list is exhausted,
  C >= 10 ,                            %   and the carry is 10+,
  R is C rem 10 ,                      %   the next digit in the result is the carry modulo 10
  Q is C div 10 ,                      %   take the quotient
  multiply( [] , _ , Q , Rs )          %   and recurse down with the quotient as the carry
  .                                    %
multiply( [D|Ds] , N , C , [R|Rs] ) :- % if the list is NOT exhausted,
  T is D*N + C ,                       %   compute the product for this digit
  R is T rem 10 ,                      %   the next digit in the result is that product modulo 10
  Q is T div 10 ,                      %   the next carry is the quotient
  multiply( Ds , N , Q , Rs )          %   recurse down
  .                                    $ Easy!