سؤال

لدي قائمة بالقوائم، وأحتاج إلى العثور على أطول واحد منهم. إذا كان هناك أكثر من واحد بنفس الطول، فهذا هو نفسه الذي يعود إليه. شكرا.

هل كانت مفيدة؟

المحلول

إليك المسند العام الذي يقوم بمسح قائمة للعثور على عضو واحد يحدده هدف معين.

select_element(Goal, [Head | Tail], Selected) :-
    select_element(Goal, Tail, Head, Selected).


select_element(_Goal, [], Selected, Selected).

select_element(Goal, [Head | Tail], Current, FinalSelected) :-
    call(Goal, Head, Current, Selected),
    select_element(Goal, Tail, Selected, FinalSelected).

دعنا نقول أنك تحدد المسند

get_bigger_number(N1, N2, N) :-
    N is max(N1, N2).

الآن يمكنك تنفيذ:

?- select_element(get_bigger_number, [5, 1, -2, 10, 3.2, 0], Selected).

Selected = 10

لذلك كل ما عليك فعله الآن هو تحديد المسند get_longer_list(L1, L2, L)واستخدامها بدلا من get_bigger_number/3.

بالطبع، باستخدام المسند العام select_element/3 قد لا تكون فعالة جدا. على سبيل المثال، يجب أن تحاول تجنب حساب طول القائمة نفسها عدة مرات، لأن هذا الحساب بطيء في PROLOG (على الأقل إذا تم تنفيذه في PROLOG بالطريقة القياسية).

نصائح أخرى

يرجى النظر في بلدي aproach.

longest([L], L) :-
   !.
longest([H|T], H) :- 
   length(H, N),
   longest(T, X),
   length(X, M),
   N > M,
   !.
longest([H|T], X) :-
   longest(T, X),
   !.

ثم يمكنك استشارة ذلك:

?- longest([[1]], N).
N = [1] ;

?- longest([[1],[2]], N).
N = [2] .

?- longest([[1],[2], [3,3,3], [2]], N).
N = [3, 3, 3] ;

?- longest([[1],[2], [3,3,3], [2]], N).
N = [3, 3, 3].

?- longest([[1],[2], [3,3,3], [2], [4,4,4,4]], N).
N = [4, 4, 4, 4] .

?- longest([[1],[2], [3,3,3], [2], [4,4,4,4]], N).
N = [4, 4, 4, 4] ;

تحية!

نحدد longest/2 مرتكز على max_of_by/3 المستخدمة في جنبا إلى جنب مع length/2:

longest(Xss,Ys) :-
   max_of_by(Ys,Xss,length).

استعلامات عينة:

?- longest([[1],[2]],Xs).      % we expect   multiple solutions
  Xs = [1]                
; Xs = [2].                    % we    _get_ multiple solutions

?- longest([[2,1,3],[7,5],[1,8,2,3,1],[2,7,1,4]],Xs).
Xs = [1,8,2,3,1].              % succeeds deterministically

إليك نهج آخر فعال وسهل الفهم. هذه الفكرة هي العثور على أطوال جميع القوائم في القائمة، واستخدام max_list للحصول على طول قائمة أطول، ثم ابحث عن قائمة طويلة. هذا له الفائدة التي سيعود جميع قوائم أطول طول.

lengths([],[]).
lengths([H|T], [LH|LengthsT]) :-
    length(H, LH),
    lengths(T, LengthsT).

lengthLongest(ListOfLists, Max) :-
    lengths(ListOfLists, Lengths),
    max_list(Lengths, Max).

longestList(ListOfLists, Longest) :-
    lengthLongest(ListOfLists, Len),
    member(Longest, ListOfLists),
    length(Longest, Len).

% Correct again.

longest(LL,LX) :-
        findmax(Len,(append(_,[L|_],LL),length(L,Len)),MaxLen),
        append(_,[LX|_],LL),
        length(LX,MaxLen).

findmax(V,P,Max) :-
        findall(V,P,L),
        max(L,Max).

max([N],N) :- !.
max([N|R],Max) :-
        max(R,Max2),
        max3(N,Max2,Max).

max3(N,Max2,N) :- N > Max2,!.
max3(N,Max2,Max2).

للحصول على طول قائمة أطول:

%sample: longest([[2,1,3],[7,5],[1,8,2,3,1],[2,7,1,4]],L,LEN).

longest([L], L, _) :-
   !.
longest([H|T], H, _) :-
   length(H, N),
   longest(T, X, N),
   length(X, M),
   N > M,
   !.
longest([_|T], X, LEN) :-
   length(X, LEN),
   longest(T, X, LEN),
   !.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top