Moim problemem jest:

Napisz program Prolog, który, biorąc pod uwagę dwie listy indeksów całkowitych i wartości, zwraca listę, której pierwszym elementem jest wartość zapisana w pozycji odpowiadającej pierwszym elementowi indeksów wartości listy. Na przykład, biorąc pod uwagę indxs = [2,1,4,3] i wartości = [2,4,68], wyjście wynosi [4,2,8,6].

Do tej pory zrobiłem:

newlist([], [], void).
newlist([void|Tail], Values, X) :- newlist(Tail, Values, X).

newlist([H|T], Values, X) :- 
   nth1(H, Values, Curr), %%Get element nr H in Values and bind it to Curr
   add(Curr, X, [Curr|X]), %%Add Current to array X
   newlist(T, Values, X). %%Recursive send back Tail, the values and new array X

I zapytać:

newlist([2,1], [2,3], X).

Jeśli mój kod Prolog jest OK, chcę pokazać moją nową listę w zmiennej X. Jak mogę to zrobić? (Już próbowałem go wydrukować.

1
user8997599 4 czerwiec 2018, 21:52

3 odpowiedzi

Najlepsza odpowiedź

Jesteś blisko rozwiązania. Najprostszym przypadkiem jest, gdy lista indeksów jest pusta. W takim przypadku lista wartości nie ma konsekwencji, a wynik jest pustą listą:

values([], _, []).

_ jest zmienną anonimową . Można go traktować jako "niestabilna zmienna". Jeśli lista indeksów nie jest pusta, musimy przejść do listy i, dla każdego indeksu pobrać odpowiednią wartość w tej pozycji:

values([Index| Indexes], Values, [SelectedValue| SelectedValues]) :-
    nth1(Index, Values, SelectedValue),
    values(Indexes, Values, SelectedValues).

Predykat nth1/3 to wspólny predykat biblioteki, który można znaleźć zaimplementowany w kilku systemach Prologów. Jeśli nie jest dostępny w systemie Prologu, którego używasz, definiując, to dobre ćwiczenie do nauki Prologu.

Korzystanie z przykładu jako zapytania próbki:

?- values([2,1,4,3], [2,4,6,8], SelectedValues).
SelectedValues = [4, 2, 8, 6].
0
Paulo Moura 4 czerwiec 2018, 19:42

Dla zabawy można również użyć maplist.

Definiuj nth_value, aby przenieść argumenty nth1 do wygodnego zamówienia:

nth_value(Values, Index, Item) :- nth1(Index, Values, Item).

Następnie:

newlist(INDXS, VALUES, R) :- maplist(nth_value(VALUES), INDXS, R).
2
lurker 4 czerwiec 2018, 20:17

Istnieje standardowa sztuczka, która osiąga to, parując wskaźniki i wartości, a także sortowanie Sortowanie , ponieważ pary są posortowane w kolejności Leksykograficzne . Wskaźniki zostaną posortowane, a wartości zostaną przeciągnięte razem z nimi i znajdą się we właściwych miejscach:

pair_up( X, Y, X-Y).
second( _-Y, Y).

newlist( Idxs, Vals, R) :- 
     maplist( pair_up, Idxs, Vals, L), 
     sort( L, S), 
     maplist( second, S, R).

Jest niezależny od schematu indeksowania: zarówno indeksowanie 0-, jak i 1 będzie działać.

Kolejną zaletą jest to, że jest to linearytmiczny (ze względu na sortowanie), w przeciwieństwie do wielokrotnego powtarzanego nth kwadratowe.

Zakłada się jednak, że jesteś tylko przestawianie sekwencję, tj. Oba listy argumentów Idxs i Vals są tej samej długości.

0
Will Ness 7 czerwiec 2018, 05:00