2011-11-18 26 views
8

मैं इतना है कि सूची [1,2,3,4,5] में विभाजित विभाजन परिभाषित करने की जरूरत छमाही में एक सूची:स्प्लिट

a = [1,2,3} 

b = [4,5] 

मैं एक त्रुटि है कि "Arguments are not sufficiently instantiated" कहते हो रही है, और मैं पर्याप्त जानकारी नहीं है के बारे में पता लगाने की भाषा मेरी समस्या क्या है, या अगर मेरा डिजाइन भी सही है। किसी भी मार्गदर्शन की सराहना की जाएगी।

append([],L2,L2). 
append([H|T],L2,[H|L3]) :- append(T,L2,L3). 

lengthIs([],N). 
lengthIs([H|T],N) :- lengthIs(T,M), N is M+1. 

divide([],[],[]). 
divide([H|T],L2,L3) :- 
    ( lengthIs(L2, M) < lengthIs(L1,N)/2 
    -> divide(T, append(L2, H, X), L3) 
    ; divide(T, L2, append(L3,H,Y)) 
    ). 
+2

आपके द्वारा उत्तर के रूप में चेक किया गया समाधान 'div ([1,2,3,4,5], [1,2,3], [4,5]) के लिए विफल रहता है। कंकाल परिणाम सूची बनाने के लिए 'लंबाई/2' का उपयोग करने के लिए' – false

उत्तर

8

चलो विधेय एक और अधिक रिलेशनल नाम देना चाहिए: list_half_half/3

list_half_half(Xs, Ys, Zs) :- 
    length(Xs, N), 
    H is N - N // 2, 
    length(Ys, H), 
    append(Ys, Zs, Xs). 

length/2 और append/3 व्यावहारिक रूप से सभी हाल ही Prologs में पूर्वनिर्धारित कर रहे हैं।

यह जीएनयू Prolog है:

| ?- append(L,_,[a,b,c,d]), list_half_half(L,H1,H2). 

H1 = [] 
H2 = [] 
L = [] ? ; 

H1 = [a] 
H2 = [] 
L = [a] ? ; 

H1 = [a] 
H2 = [b] 
L = [a,b] ? ; 

H1 = [a,b] 
H2 = [c] 
L = [a,b,c] ? ; 

H1 = [a,b] 
H2 = [c,d] 
L = [a,b,c,d] 
+1

+1। –

4

संलग्न, एक पूर्व निर्धारित विधेय है ताकि समस्या हो सकती है:

तो यहाँ क्या मैं अब तक राशि है http://en.wikibooks.org/wiki/Prolog/Lists#The_append_predicate

तुम भी lengthIs में परिभाषित किया गया कभी नहीं 'एन' - आप खाली सूची को 0 के रूप में सेट करने की आवश्यकता है, एन/ पर एक आकार का कार्य भी संभव है

अंडरस्कोर प्रोलॉग को बताता है कि हमें उस वास्तविक परिभाषा में उस बिट की परवाह नहीं है।

कुछ इस तरह काम

divide(L1,L2,L3):- append(L2,L3,L1), 
        samesize(L2,L3). 
divide(L1,L2,L3):- append(L2,L3,L1), 
        onebigger(L2,L3). 
samesize(A,B):- size(A,N), 
        size(B,N). 
onebigger(A,[_|T]):- size(A,N), 
        size(T,N). 
size([],0). 
size([H|T],N):- size(T,M+1). 
2

आकार की जाँच करने की कोई ज़रूरत नहीं। बस इसे इस तरह है: यह संख्याओं की तुलना नहीं है, लेकिन शर्तें:

div([],[],[]). 
div([A],[A],[]). 
div([A,B|T],[A|X],[B|Y]) :- div(T,X,Y). 
+2

ध्यान दें कि यह समाधान वास्तव में ओपी विनिर्देश के अनुरूप नहीं है क्योंकि यह 'div ([1,2,3,4,5], [1, 3, 5], [2, 4])' div की बजाय ([1, 2, 3, 4, 5], [1, 2, 3], [4, 5]) '। – salva

+2

@ कॉन्स्टेंटिन वेविट्ज़: यह '[1,2,3,4,5] '' 1,3,5] 'और' [2,4] 'में विभाजित है। यह इसे सही लंबाई के साथ 2 सूची में विभाजित करता है, लेकिन सही * सामग्री * नहीं। –

2

निश्चित रूप से यह कोड (lengthIs(L2, M) < lengthIs(L1,N)/2 -> ...) के प्रभाव को आप क्या उम्मीद नहीं है।

lengthIs(L2, M), lengthIs(L1, N), M < N/2 -> ... 

गलती की तरह एक और टाइपो: lengthIs/2 के पहले खंड

lengthIs([],0). 
5

पढ़ना चाहिए यह सबसे कारगर समाधान सबसे Prolog कार्यान्वयन के लिए अपने विनिर्देशन के अनुरूप है आप इसे इस तरह से लिखना चाहिए:

divide(L, A, B) :- 
    divide1(L, L, A, B). 

divide1([], L, [], L). 
divide1([_|T], [H|L], [H|A], B) :- 
    divide2(T, L, A, B). 

divide2([], L, [], L). 
divide2([_|T], L, A, B) :- 
    divide1(T, L, A, B). 

यदि आप कोई आपत्ति नहीं है जो तत्वों उप-सूचियों में जहाँ तक वे समान लंबाई के हैं (Konstantin वेईत्ज़ पद से समाधान के रूप में) जाना है, तो आप ca n उपयोग:

divide([], [], []). 
divide([H|T], [H|A], B) :- divide(T, B, A). 
+1

आपका समाधान समाप्त होता है अगर पहली या दूसरी सूची की लंबाई ज्ञात है। तो 'विभाजित करें (एल, ए, बी) terminates_if बाध्य (एल); बाध्य (ए)। 'लेकिन यह अभी भी' विभाजन (एल, ए, []) के लिए समाप्त नहीं होता है। 'यहां दो उत्तरों की उम्मीद है! 'एल = [], ए = []; एल = [एक्स], ए = [एक्स] ' – false

+0

हां, उस भविष्यवाणी को 'विभाजन (+, -, -)' के रूप में उपयोग करने की उम्मीद है। – salva

+1

आप पहले से ही '+, -, -' से बेहतर हैं! वहां 'विभाजन (एल, [ए], एच)' और यहां तक ​​कि 'विभाजित ([ए | _], [बी | _], _)' अच्छी तरह से समाप्त हो जाता है। – false

0

एक और जवाब है, एक बहुत बैकट्रेस का उपयोग करता है, बहुत performant है, हालांकि नहीं है। append और length पूर्वनिर्धारित जा करने के लिए ग्रहण कर रहे हैं:

divide(A,B,C):- 
    append(B,C,A), 
    length(B,B_Length), 
    length(C,C_Length), 
    (B_Length = C_Length; 
     B_Length =:= C_Length +1). 

ओह, माफ करना, सिर्फ देखा है कि यह फिलिप व्हाइटहाउस से जवाब की एक rephrasing की तरह है।

0

इस तरह मैंने इसे किया।लगभग कोई अंतर्निहित नहीं:

split_list_in_half(Xs , H , T) :- 
    list_length(X , L) , 
    LL = L - (L // 2) , 
    take_first(Xs , LL , H , T) , 
    . 

list_length(L , N) :- 
    list_length(L , 0 , N) 
    . 

list_length([] , N , N). 
list_length([X|Xs] , T , N) :- 
    T1 is T+1 , 
    list_length(Xs , T1 , N) 
    . 

take_first(Xs , N , Pfx , Sfx) :- 
    take_first(Xs , N , [] , P1 , Sfx) , 
    reverse(P1 , Pfx) 
    . 

take_first([]  , _ , H , H , [] ). 
take_first([X|Xs] , 0 , H , H , [X|Xs]). 
take_first([X|Xs] , N , H1 , H , T  ) :- 
    N > 0 , 
    N1 = N-1 , 
    take_first(Xs , N1 , [X|H1] , H , T) 
    . 
संबंधित मुद्दे