2013-05-08 3 views
3

L 오른쪽 NM 회전에 의해 형성된 새로운 목록 술어, rotate(L,M,N)에 작업 시간.프롤로그 : 회전 목록 N 바로

내 접근 방식은 단지 M의 꼬리를 머리에 N 번 추가하는 것이 었습니다.

rotate(L, M, N) :- 
    ( N > 0, 
     rotate2(L, M, N) 
    ; L = M 
    ). 

rotate2(L, [H|T], Ct) :- 
    append(T, [H], L), 
    Ct2 is Ct - 1, 
    rotate2(L, T, Ct2). 

현재, 내 코드에 상관없이에 설정되어있는 것을 N, 원래 M 동일 L을 반환하지 않습니다. 내가 재귀 할 때처럼 보이지만 꼬리가 머리로 제대로 이동하지 않습니다.

+1

힌트 : 'append'를 두 번 호출하면 훨씬 효율적으로 작업을 수행 할 수 있습니다. –

+0

@larsmans 추가 전화는 두 번입니까? 계속해서 N을 줄여야합니까? –

답변

8

당신은 목록을 분할 append을 사용할 수 있으며, length이 목록을 만들 :

% rotate(+List, +N, -RotatedList) 
% True when RotatedList is List rotated N positions to the right 
rotate(List, N, RotatedList) :- 
    length(Back, N),   % create a list of variables of length N 
    append(Front, Back, List), % split L 
    append(Back, Front, RotatedList). 

주 : N < = 길이 (L)이에서만 작동합니다. 산술을 사용하여이를 수정할 수 있습니다. 선명도 에 대한

편집이 술어는 목록과 선언문이 호출하지 않을 때 변수 N 인수 정의된다. Prolog에서 컨벤션은 출력 인수 이전에 엄격하게 입력 인수가 있어야하기 때문에 실수로 원래 질문에서 인수를 재정렬했습니다. 따라서 목록N 및 입력 인수 RotatedList은 출력 인수입니다.

?- rotate([a,b,c], 2, R). 
?- rotate([a,b,c], 1, [c,a,b]). 

그러나이 : ​​

?- rotate(L, 2, [a,b,c]). 

는 무한 재귀로 이동합니다 하나의 답을 찾는 후 그래서이 올바른 쿼리입니다.

SWI-Prolog 설명서를 읽을 때 length에서와 같이 "?"로 표시된 조건 자 인수가 있는지 확인하십시오. 이 예제와 같이 사용할 수 있습니다.

+0

'N> 길이 (L)'에 대해이 작업을 수행하는 방법을 보지 못했습니다. N의 값을 변경/추적하면서 순환하는 일종의 재귀 호출이 필요한 것처럼 보입니다. 그러나 이는 복잡한 것을 넘는 것처럼 보입니다. –

+0

@AdamDuvall Modular arithmetic –

+0

그래서'N> length (L)'이면 mod를 사용하여 어떤 시점에서 멈추고 시간이 초과되지 않는다는 아이디어가 있습니까? –