2014-10-17 3 views
3

목록에서 하나의 요소를 세고 다른 요소가 나타나는 곳에서 카운팅을 멈추고 다음 요소로 건너 뛰고 싶습니다.동일한 요소를 계산합니다. Prolog

답변은 다음과 같이해야한다 : 나는 count/3을 위해 쓴

?- count(a,[a,a,a,a,b,a,a,a],X). 
X = [4,3] 

?- count(a,[a,a,a,b,a,b,a,a,b,a,a,a,a],X). 
X = [3,1,2,4] 

코드는 다음과 같습니다

count(_, [], []). 
count(X, [X | T], N) :- 
    count(X, T, N1), 
    !, 
    N is N1 + 1. 
count(X, [_ | T], N) :- 
    count(X, T, N). 

나는 그것이 숫자의 목록을 반환하는 방법을 모른다. 아무도 도와 줄 수 있습니까? 감사합니다. .

+2

귀하의 질문은 상당히 모호하므로 입력을 위해 3 : 2 대신에 4 개의 인수를 사용하고, 출력에는 1, 현재 마비에는 1을 사용합니다. 요소가 발견되었습니다 (초기 값은 0). – Steven

+0

@ 케이, 실제로 내가 입력 한 목록에는 두 개의 다른 요소가 포함되어 있습니다. 하나만 계산하면 결과는 그 요소를 계산해야합니다. 예를 들어 입력 수 (a, [a, a, b, a, b, a, a, b, a, a, a, a], X) 그리고 출력은 X = [3,1,2,4] –

답변

1

내 대답에 아이디어는 run lengths 개방의 목록을 유지하고, 실행 인 경우에 그것을에 새로운 요소를 추가하는 것입니다

count(_, [], []). 
count(Item, [Head|Tail], Counts) :- 
    count(Item, [Head|Tail], 0, Counts). 
count(_, [], CurrentCount, [CurrentCount]). 

count(Item, [Item|Tail], CurrentCount, Counts) :- 
    CurrentCountP1 is CurrentCount + 1, 
    count(Item, Tail, CurrentCountP1, Counts). 
count(Item, [Head|Tail], CurrentCount, [CurrentCount|Counts]) :- 
    dif(Head, Item), 
    count(Item, Tail, 0, Counts). 
다음
?- count(a,[a,a,a,b,a,b,a,a,b,a,a,a,a], X). 
X = [3, 1, 2, 4] ; 
false. 
+0

예. 정확하게 얻고 싶습니다. 감사합니다. –

+0

'count/3'에서'count/4'로 갈 때, 입력리스트를 if-then-else를 사용하여'count/4'의 마지막 두 절을 결합합니다. 이는 샘플 쿼리에서 볼 수있는 가짜 선택 지점을 제거합니다 (물론 대부분의 시스템에서 첫 번째 인수 인덱싱이 일반적인 것으로 가정 함). –

3

당신이 그것을 할 수있는 방법과 보존 ! 다음에

, 우리는 메타 술어 ( splitlistIfAdj/3, tfilter/3maplist/3)을 사용하는 용어 평등/불평등 술어 ( (=)/3dif/3)을 구체화. 실행 Xs1
 
?- Xs0 = [a,a,a,b,a,b,a,a,b,a,a,a,a], splitlistIfAdj(dif,Xs0,Xs1). 
Xs0 = [ a,a,a, b, a, b, a,a, b, a,a,a,a ], 
Xs1 = [[a,a,a],[b],[a],[b],[a,a],[b],[a,a,a,a]]. 

  • 목록 : Xs1실행 항목의Xs0에서를 포함 할 수

    1. 첫째 :

      의이 E = aXs0 = [a,a,a,b,a,b,a,a,b,a,a,a,a]을 가지고 단계별로 count/3 단계를 구축하자 모두 실행 중입니다. Xs2에는 관심있는 앱만 포함되어 있습니다.

       
      ?- Xs1 = [[a,a,a],[b],[a],[b],[a,a],[b],[a,a,a,a]], tfilter(\[X|_]^(X=a),Xs1,Xs2). 
      Xs1 = [[a,a,a],[b],[a],[b],[a,a],[b],[a,a,a,a]], 
      Xs2 = [[a,a,a], [a], [a,a], [a,a,a,a]]. 
      

    2. 거의 완료되었습니다. 마지막으로, 우리는 각각의 실행에 Xs2 (E -runs의 목록을)지도 Xs 길이 :

       
      ?- Xs2 = [[a,a,a],[a],[a,a],[a,a,a,a]], maplist(length,Xs2,Xs). 
      Xs2 = [[a,a,a],[a],[a,a],[a,a,a,a]], 
      Xs = [  3, 1, 2,  4]. 
      

    3. 이제

    , 코드의 완성!

     
    count(E,Xs0,Xs) :- 
        splitlistIfAdj(dif,Xs0,Xs1), 
        tfilter(E+\[X|_]^(X=E),Xs1,Xs2), % works for _any_ item E 
        maplist(length,Xs2,Xs). 
    

    의 일부 쿼리를 실행하자 : 코드 모노톤이므로

    ?- count(a,[a,a,a,a,b,a,a,a],Xs). 
    Xs = [4,3].       % succeeds deterministically 
    ?- count(a,[a,a,a,b,a,b,a,a,b,a,a,a,a],Xs). 
    Xs = [3,1,2,4].      % succeeds deterministically 
    

    을, 우리는 너무,보다 일반적인 쿼리에 대한 논리적으로 사운드 답변를 얻을 :

    ?- count(E,[a,a,a,b,a,b,a,a,b,a,a,a,a],Xs). 
    Xs = [3,1,2,4], E = a    ; 
    Xs = [1,1,1], E = b    ; 
    Xs = [],  dif(E,a), dif(E,b) . 
    
  • 관련 문제