2010-12-07 48 views
7

Tôi bắt đầu chơi với prolog, và với một nền Java nó thực sự khó khăn cho tôi vì vậy đây là một câu hỏi ngớ ngẩn:Cách tính chỉ mục của phần tử trong danh sách?

Làm thế nào bạn sẽ viết một chỉ số indexOf có thể cung cấp cho chỉ số của một phần tử đã cho danh sách ?

câu hỏi đầu tiên của tôi là về arity vị: Tôi đoán nó phải là 3 như:

indexOf(List,Element, Index) :- ...... 

Am tôi phải không? Có thể điều này đã tồn tại trong các thư viện tích hợp nhưng tôi muốn học cách viết nó. Cảm ơn bạn đã giúp đỡ.

+0

Trông giống như một khởi đầu tốt. – aschepler

+0

@aschepler có nhưng tôi phát điên khi có vị ngữ nhỏ này hoạt động !!! –

+0

Đây thực sự là một bài tập tốt khi học prolog. FYI: công trình dự đoán để đạt được điều này là 'nth0' và' nnth1'. (http://www.swi-prolog.org/pldoc/doc_for?object=section%282,%27A.12%27,swi%28%27/doc/Manual/lists.html%27%29%29) – Cephalopod

Trả lời

11

Bạn có thể làm điều đó một cách đệ quy: Giả sử chỉ số 0 dựa trên (nếu không chỉ cần thay đổi 0 bằng 1 ở mệnh đề đầu tiên)

indexOf([Element|_], Element, 0). % We found the element 
indexOf([_|Tail], Element, Index):- 
    indexOf(Tail, Element, Index1), % Check in the tail of the list 
    Index is Index1+1. % and increment the resulting index 

Nếu bạn muốn chỉ để tìm sự xuất hiện đầu tiên, bạn có thể thêm một vết cắt (!) để tránh backtracking.

indexOf([Element|_], Element, 0):- !. 
indexOf([_|Tail], Element, Index):- 
    indexOf(Tail, Element, Index1), 
    !, 
    Index is Index1+1. 
+0

cảm ơn câu trả lời. Tôi có thể thay thế mệnh đề đầu tiên bằng: indexOf ([First | _], Element, Index): - Đầu tiên == Element, Index == 0.? –

+0

Câu trả lời là KHÔNG. Bạn có thể giải thích lý do tại sao ? –

+0

Toán tử == không thực hiện hợp nhất. Vì vậy, nó không thể khởi tạo Index thành 0. Nó có thể được sử dụng, tuy nhiên, trong lần so sánh đầu tiên (First == Element sẽ là tốt bởi vì trong vị từ đó cả hai thuật ngữ nên được khởi tạo). Index == 0 sẽ thất bại khi Index không được khởi tạo. – gusbro

1

Người ta phải thích sử dụng đuôi-đệ quy:

indexOf(V, [H|T], A, I) 
:- 
    Value = H, A = I, ! 
; 
    ANew is A + 1, 
    indexOf(V, T, ANew, I) 
. 

indexOf(Value, List, Index) 
:- 
    indexOf(Value, List, 0, Index) 
. 

indexOfWithoutFailure(Value, List, Index) 
:- 
    indexOf(Value, List, 0, Index) 
; 
    Index = -1 
. 

Một số ví dụ truy vấn:

?- indexOf(d, [a, b, c, d, e, f], Index). 
Index = 3. 

?- indexOf(x, [a, b, c, d, e, f], Index). 
false. 

?- indexOfWithoutFailure(x, [a, b, c, d, e, f], Index). 
Index = -1. 

Nếu bạn muốn để có được tất cả các chỉ số của một phần tử trong một danh sách, bạn nên viết một vị từ khác cho nó mà không cần cắt có tên là allIndexesOf hoặc một cái gì đó.

0

Tôi làm điều này trong ký hiệu thừa và nó khá ngắn gọn và gọn gàng: kết quả đầu ra

index([V|_],V,0). 
index([_|T],V,s(I)) :- index(T,V,I). 

mẫu:

?- index([a,b,c,a],a,X). 
X = 0 ; 
X = s(s(s(0))) ; 
false. 

?- index(List,a,s(0)). 
List = [_G1710, a|_G1714]. 
Các vấn đề liên quan