2013-05-08 3 views
2

sublist(L1,L2,I,J)프롤로그 - 하위 목록

나는 목록 L1 2 개 인덱스 IJ과 함께 전달되고 있고, 내가 L2IJ 사이의 요소를 포함하는 포괄적 인 서브리스트가되고 싶어요 압축을 풉니 다.
J이 범위를 벗어나는 경우 I에서 목록 끝으로 이동하고 싶습니다. 마찬가지로 I이 0보다 작 으면 목록 시작 부분에서 J으로 이동합니다. I>J은 빈 목록을 반환합니다.

sublist(_,[],I,J):- 
    I > J. 
sublist(Xs,Ys,I,Length):- 
    length(Xs,Length), 
    N > L, 
    sublist(Xs,Ys,I,J). 
sublist([X|_],[X],1,1). 
sublist([X|Xs],[X|Ys],1,J):- 
    J > 1, 
    J1 is J - 1, 
    sublist(Xs,Ys,1,J1). 
sublist([_|Xs],Ys,I,J):- 
    I > 1, 
    I1 is I - 1, 
    J1 is J - 1, 
    sublist(Xs,Ys,I1,J1). 
+0

그리고 * 당신은 무엇을 지금까지 * 어떤 문제가 있습니까? 여기 사람들은 당신에게 답을주기위한 것이 아니라 오히려 설명을하기로되어 있습니다. – Rubens

+0

@Rubens 오, 죄송합니다, 포함하는 것을 잊었습니다. 두 번째 술어가 작동하지 않습니다. 현재'I'와'J'가 목록에 있어야합니다. –

답변

4

당신은 당신의 전략을 재검토하여이를 해결할 수 있습니다 : 나는 지금까지 무엇을 가지고

.

우선, 기본 사례는 무엇입니까?

  • 당신은 당신은 그 두 경우 모두에서 I > J

  • 입력으로 빈 목록으로 결국, 당신은 당신이 지금까지 가지고 무엇에 빈 목록을 추가하고, 좋은 그것을 부를 것이다 .

    다음으로 신경 쓰는 가장자리 사건은 무엇입니까?

    • J 당신은 입력 목록의 끝에 통과,
    • I 목록 첫 번째 경우에

    의 시작 앞에있는 목록의 끝을 넘어이다. 두 번째 단계에서는 입력 목록의 시작 부분부터 시작합니다.

    좋아요, 시도해 보겠습니다. 축전기를 사용하고 주변에서 호출을 감쌀 것입니다.

    sublist(L1, L2, I, J):- 
        sublist(L1, Temp, I, J, []), 
        !, 
        reverse(Temp, L2). 
    

    우리는 우리의 출력에서 ​​L2로 통일 입력리스트 L1을, 변수를 가지고, 상기 인덱스, 및 IJ. 난 cut 그래서 내가 다른 솔루션에 대한 backtracking에 대해 걱정할 필요가 없으며, 그것을 역전 누적 된 목록이 반대로 내장되어 있기 때문에.

    기본 케이스에 대해 작업 해 보겠습니다.

    빈 목록을 입력으로 사용하여 누적기를 출력 목록으로 통합하면됩니다. 우리는이 시점에서 지표에 관심이 없다. 결과적으로, 이것은 또한 J이리스트의 끝을 넘는 엣지 경우를 만족시킵니다. 이 시점에서 우리는 모든 입력리스트를 누산기에 축적하고 여전히 J 값을 남겨 둘 것입니다.

    sublist([], L2, _I, _J, L2). 
    

    I> J 또한 출력 목록으로 누적기를 통합하십시오. 더 이상 입력 목록에 신경 쓰지 않습니다.

    sublist(_L1, L2, I, J, L2):- 
        I > J. 
    

    이제 가장자리 경우.

    J 위 목록의 끝 부분을 해결했습니다.

    I은 목록의 시작 앞에 있고, 그 색인을 0으로 설정하고 계속 이동하십시오.

    sublist(L1, L2, I, J, L2):- 
        I < 0, 
        sublist(L1, L2, 0, J, L2). 
    

    이제 실제 로직을 구현하면됩니다. 올바른 I부터 시작하여 누적되기를 원합니다. 따라서 I을 감소시키고 우리가 원하는 위치에 도달 할 때까지 입력리스트를 버리자. 색인의 끝을 일치 시키려면 J도 줄여야합니다. 이 방법으로 우리는 인덱스 사이의 동일한 거리를 유지합니다.

    sublist([_L|Ls], L2, I, J, Acc):- 
        I > 0, 
        sublist(Ls, L2, I-1, J-1, Acc). 
    

    우리는 마침내 우리가되고 싶은 곳입니다. 이제 입력 목록의 조각으로 목록을 작성해 봅시다. 이것은 우리가 기본 사례 중 하나를 치기 전까지 계속됩니다. 그런 다음 누적 기가 원래 sublist 절로 반환됩니다. 모든 퍼팅

    sublist([L|Ls], L2, I, J, Acc):- 
        sublist(Ls, L2, I, J-1, [L|Acc]). 
    

    함께 우리와 끝까지 :

    sublist(L1, L2, I, J):- 
        sublist(L1, Temp, I, J, []), 
        !, 
        reverse(Temp, L2). 
    sublist([], L2, _I, _J, L2). 
    sublist(_L1, L2, I, J, L2):- 
        I > J. 
    sublist(L1, L2, I, J, L2):- 
        I < 0, 
        sublist(L1, L2, 0, J, L2). 
    sublist([_L|Ls], L2, I, J, Acc):- 
        I > 0, 
        sublist(Ls, L2, I-1, J-1, Acc). 
    sublist([L|Ls], L2, I, J, Acc):- 
        sublist(Ls, L2, I, J-1, [L|Acc]). 
    

    그리고 우리는 지금처럼 테스트 할 수

    ?- sublist([1,2,3,4,5], S, 0,3). 
    S = [1, 2, 3, 4]. 
    
    ?- sublist([1,2,3,4,5], S, -1,30). 
    S = [1, 2, 3, 4, 5]. 
    
    ?- sublist([1,2,3,4,5], S, 3,1). 
    S = []. 
    
    ?- sublist([1,2,3,4,5], S, 3,3). 
    S = [4]. 
    
    ?- sublist([1,2,3,4,5], S, 3,4). 
    S = [4, 5]. 
    
  • +1

    +1 우수하고 심층적 인 답변입니다. 'is/2' 부족에 대해 약간 걱정했지만 분명히'/2'는 산술 표현식에서 작동합니다. –

    +0

    결과를 하향식 방식으로 작성하는 것이 더 많은 Prologish이며 논쟁의 여지가 있으며 직관적이어야합니다. :) 역시 끝낼 필요가 없습니다. –

    0

    나는 당신이 두 번째 절에 그냥 오타가 있다고 생각. 귀하의 요구 사항에 맞춰야하는이 (시도되지 않은) 교정을 시도하십시오.

    J가 범위를 벗어나는 경우 I부터 목록의 끝까지 가고 싶습니다.

    sublist(Xs,Ys,I,J):- 
        length(Xs,Length), 
        J > Length, 
        sublist(Xs,Ys,I,Length).