0

我必须在 turbo prolog 中解决以下问题作为家庭作业:“确定以列表中的数字表示的数字与给定数字的乘积。例如:[1 9 3 5 9 9] * 2 --> [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 谓词之前一切正常。我只是找不到将产品的数字添加到最终列表中的方法。任何人都可以帮我解决问题吗?谢谢。

4

2 回答 2

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!
于 2013-10-21T16:57:21.307 回答
0

addDigit 对我来说似乎是错误的:您只使用第一个,而未指定尾部!尝试

addDigit(NR,[DIGIT|Ns]):-
    NR>0,
    DIGIT = NR MOD 10,
    NR1 = NR DIV 10,
    addDigit(NR1, Ns).
于 2013-10-20T13:23:34.800 回答