2013-10-20 5 views
0

터보 프롤로그에서 다음과 같은 문제를 해결해야합니다. "목록의 숫자로 표시된 숫자의 제품을 주어진 숫자로 확인하십시오. 예 : [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 조건부까지는 모두 정상입니다. 제품의 숫자를 최종 목록에 추가하는 방법을 찾지 못했습니다. 누구든지 해결책을 도울 수 있습니까? 감사합니다. .

답변

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! 
+0

덕분에, 내 시도 솔루션보다 실제로 훨씬 더 간단합니다 – user2899733

0

addDigit는 나에게 잘못된 것 같습니다 : 당신은 처음 만 사용하고 꼬리는 지정하지 마십시오! 시도해보십시오.

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