2013-04-10 4 views
1

두 목록의 항목을 합한 결과를 다른 목록에 표시하는 프롤로그 프로그램을 작성하려고합니다.프롤로그 - 두 목록의 숫자 합계

목록 1 :

[1, 3, 4, 2] 

목록 2 : 예를 들어

[5, 1, 3, 0] 

결과 :

[6, 4, 7, 2] 

지금까지,이 있습니다

,
list_sum([],[],[]). 
list_sum([H1|T1],[H2|T2],L3):-list_sum(T1,T2,[X|L3]), X is H1+H2. 

?-list_sum([1,2,3,4],[1,2,3,4],R),write(R). 

답변

1

거의 다 왔어. 문제는 합계의 결과가 재귀 호출이 아닌 두 번째 절의 머리에 있어야한다는 것입니다.

list_sum([H1|T1],[H2|T2],[X|L3]):-list_sum(T1,T2,L3), X is H1+H2. 

결과에 "반환"당신이 그것을 쓴 방법, L3 당신이 recusive 통화에서 머리 (X)을 제거한있는 목록이 있습니다; 반대로 말하면, 결과 목록에 요소 (X)를 추가하십시오.

+0

내 대답을 참조하십시오. –

+0

@ 니콜라스 케어 라이 (NicholasCarey) : 귀하의 마지막 조항에 동의하십시오, 저는 OP 문제를 보여주고 싶었고 해결 방법을 바꾸지 않고 수정하기를 원했습니다. 목록 길이가 다른 경우 절차를 성공적으로 수행하는 두 번째 및 세 번째 조항에 동의하지 않습니다. – gusbro

+0

은 오히려 요구 사항에 따라 다릅니다. * n'est-ce pas *? –

0

결과는 목록이어야하므로 X is H1+H2이라고 말할 수는 없습니다. X는 목록이 아니며 목록의 머리글 만 단일 변수와 대조하기 때문입니다. 또한 list_sum([],[],0)은 같은 이유로 올바르지 않습니다.

sum([],[],[]). 
sum([H1| T1], [H2| T2], [ResH| ResT]) :- 
     sum(T1, T2, ResT), 
     ResH is H1+H2. 

을하지만 당신은 자신의 코드를 실행하면, 첫 번째 X는 두 번째 재귀 호출 X에, H1 + H2와 일치하는 값을 가지고 있으며, T1 + T2의 머리와 일치 할 수없는 경우 : 대답은 다음과 같습니다 . 그래서 no을 출력합니다.

2

@gusbro는 말했습니다. 또한, 당신은 서로 다른 길이의 목록을 처리하는 작업의 순서를 재 배열 및 추가 특별한 경우의 몇 가지를 추가해야합니다

list_sum([]  , []  , [] ) . 
list_sum([]  , [Y|Ys] , [Z|Zs]) :- Z is 0+Y , list_sum([] , Ys , Zs) . 
list_sum([X|Xs] , []  , [Z|Zs]) :- Z is X+0 , list_sum(Xs , [] , Zs) . 
list_sum([X|Xs] , [Y|Ys] , [Z|Zs]) :- Z is X+Y , list_sum(Xs , Ys , Zs) . 

당신은 Z을 수 있도록, 내 위의 예에서 평가 (Z is X+Y)를 이동해야 재 계산보다 전에 으로 평가됩니다. 이 스택 공간을 사용하지 않는 때문에이 솔루션은 반복적 인 의미하는 술어 꼬리 재귀을하고,

  • 첫째,이 두 가지를 수행합니다. 코드에서 전체 재귀가 완료 될 때까지 평가가 수행되지 않습니다. 각 중간 합계는 스택에 보관되며 백업 중 오른쪽에서 왼쪽으로 평가됩니다. 이것은 큰 목록에 스택을 날려 버리는 것을 의미합니다.

  • 두 번째로 재귀 호출하기 전에 각 결과를 평가하면 이 빠름이 실패 함을 의미합니다. 결과와 통합되지 않는 첫 번째 합계는 전체 작업에 실패합니다. 솔루션이 느리게 실패합니다. 첫 번째 항목이 결과 목록의 첫 번째 항목과 합쳐지지 않는 10,000,000 개의 항목 목록을 고려하십시오. 10,000,000 개의 항목을 모두 통과 한 다음 —은 스택을 날려 버리지 않았다고 가정합니다. — 합계를 오른쪽에서 왼쪽으로 계산하기 시작합니다. 당신의 술어는 마지막 평가 때까지 실패하지 않을 것입니다.당신이 SWI - 프롤로그를 사용하는 경우

+0

"매우 마지막 평가가 될 때까지 .... :) 좋은 답변! –

1

는 SWI - 프롤로그 하나의 라이너입니다 '뒤로'도 작동합니다.

?- maplist(plus, [1,2,3],Y,[3,4,5]). 
Y = [2, 2, 2]. 
+0

Ahhh maplist :) – Ash

0
domains 
list=integer* 
predicates 
add(list,list,list) 
clauses 
add([],[],[]). 
add([V1X|X],[V1Y|Y],[V1Z|Z]):-add(X,Y,Z),V1Z=V1X+V1Y.