2010-05-27 9 views
6

SICP व्यायाम 2.26 में, इस योजना कोड दिया जाता है:एसआईसीपी अभ्यास में डॉ। स्किमेम का उपयोग करते हुए 2.26, सूचियों की एक जोड़ी के बजाय, एक सूची क्यों लौटाती है?

(define x (list 1 2 3)) 
(define y (list 4 5 6)) 

फिर इस विपक्ष फोन दिया जाता है:

(cons x y) 

मैं उम्मीद सूचियों की एक जोड़ी परिणाम होगा, ((1 2 3) (4 5 6)) लेकिन दुभाषिया देता है, ((1 2 3) 4 5 6) ... 4 तत्वों वाली एक सूची, पहली सूची है। वाई अलग तरीके से क्यों व्यवहार किया जाता है? मैंने स्पष्टीकरण के लिए अन्य एसआईसीपी उत्तरों को देखने की कोशिश की है, लेकिन कुछ संतोषजनक नहीं मिला। तो क्या कोई योजना/लिस्प विशेषज्ञों ने विपक्ष के इस पहलू पर कुछ प्रकाश डाला? किसी भी दृष्टिकोण के लिए अग्रिम धन्यवाद।

+1

मेरे प्रश्न, विशेष रूप से नाथन और टोनियो के सभी उत्तरदाताओं के लिए धन्यवाद। योजना/लिस्प में यह नौसिखिया अब आपके विस्तृत उत्तरों के कारण भाषा को थोड़ा बेहतर बनाता है। – limist

+0

यह भी देखें [रिकू लिस्प में rsive रेंज एक अवधि जोड़ता है?] (http://stackoverflow.com/q/16379657/1281433) इसी तरह के स्पष्टीकरण के लिए। –

उत्तर

12

'((1 2 3) 4 5 6) वास्तव में सूचियों की एक जोड़ी है। इसलिए सबसे पहले आपको प्रतिनिधित्व के बजाय मिलता है,

'((1 2 3) . (4 5 6)) 

हालांकि, प्रिंटर से बचा जाता है बिंदीदार जोड़ी अंकन जब भी यह कर सकते हैं: यहाँ एक और तरीका यह लिखने के लिए है। नियम है:

'(x . (xs ...)) 
=> 
'(x xs ...) 

किसी भी x और xs लिए। यहां, आपके x = '(1 2 3) और xs = '(4 5 6), इसलिए आपको ((1 2 3) 4 5 6) मिलते हैं।


संख्या देखने के लिए विपक्ष और डॉटेड-जोड़ी अंकन संबंधित है, की समस्या सिर्फ '(1) और '(6) को छोटा करते हैं।

(cons (cons 1 '()) (cons 6 '())) 

यहाँ, '() नहीं के बराबर, या खाली सूची है: निम्नतम स्तर रास्ता उनमें से एक जोड़ी बनाने के लिए इस है।अगर हम बिंदीदार-जोड़ी अंकन करने के लिए सचमुच यह अनुवाद करते हैं, हम इस मिल:

'((1 .()) . (6 .())) 

लेकिन क्योंकि प्रिंटर गिर बिंदीदार-जोड़ी अंकन जब भी संभव हो, तो आप इस बजाय:

'((1 .()) . (6 .())) 
=> 
'((1) . (6)) ; <-- x=1, xs=nothing; x=6, xs=nothing 
=> 
'((1) 6) ; <-- x=1, xs=6 
+0

विस्तृत स्पष्टीकरण के लिए धन्यवाद; अब मैं देखता हूं कि यह सूक्ष्म जोड़ी नोटेशन के पतन के बाद सूचियों की एक जोड़ी है, और तब से (सीडीआर (विपक्ष x y)) दूसरी सूची देता है। लेकिन क्यों (लंबाई (विपक्ष x y)) उत्तर 4? यह 6 या नहीं होना चाहिए (दोनों सूचियों के सभी तत्वों की गणना करें), या 2 (दो सूचियों की गणना करें)? – limist

+0

आह, मेरी टिप्पणी कभी भी ध्यान न दें; मुझे लगता है कि यह उस पुस्तक में दिए गए (लम्बाई) फ़ंक्शन का परिणाम है जो नेस्टेड सूचियों से निपटता नहीं है। – limist

+1

@limist: ठीक है, तरह। आपकी समस्या (मुझे लगता है) एक अपारदर्शी, अलग डेटा प्रकार के रूप में सूची के बारे में सोच रहा है। वास्तव में यह केवल एक सम्मेलन है कि विपक्ष जोड़े का उपयोग कैसे करें (टोनियो का जवाब देखें)। इसलिए, लंबाई 6 प्राप्त करने के लिए, आप 'नेस्टेड-लिस्ट' लिखेंगे, हालांकि इसे वास्तव में 'वृक्ष-आकार' कहा जाएगा क्योंकि यह विपक्ष के लिए पेड़ सम्मेलन का उपयोग करता है। दूसरी तरफ, 'लंबाई (विपक्ष (1 2 3)' (4 5 6)) से 2 प्राप्त करने के लिए, आपको * किसी भी * सूची के लिए 2 प्राप्त करना होगा। यह विधि सूची सम्मेलन को अनदेखा करती है जो कहती है कि, उदाहरण के लिए, '(1) वास्तव में '(विपक्ष 1'()) है। इसकी लंबाई 1, 2 नहीं है, क्योंकि सूचियों का निर्माण किया जाता है। –

10

cons सूची के प्रमुख के रूप में पहला तर्क, और दूसरा पूंछ के रूप में उपयोग करता है।

आप इसे एक पहली सूची (1 2 3), जो जिसके परिणामस्वरूप सूची के सिर और एक दूसरी सूची (4 5 6), सूची की पूंछ के रूप में प्रयोग की जाने वाली गठन करेंगे दे। इस प्रकार, आप ((1 2 3) 4 5 6) के साथ समाप्त होते हैं।

रिक्त सूची के साथ समाप्त होने वाली बाएं से दाएं कॉम्ब्स के रूप में सूचियों की बात, (o के रूप में प्रतिनिधित्व), और देखें कि वे कैसे गठबंधन करते हैं।

X=  Y= 
/\  /\ 
1 /\ + 4 /\  
2 /\ 5 /\ 
    3 o 6 o 

फिर आप का निर्माण:

/\ 
X Y 

प्राप्त करना:

/\ 
/\ \ 
1 /\ \ 
2 /\ \ 
    3 o/\ 
    4 /\ 
     5 /\ 
     6 o 

जो ((1 2 3) 4 5 6 है जब कोष्ठक के साथ प्रतिनिधित्व किया। और यह सूचियों की एक जोड़ी है।

+0

हां, मैंने ड्राइंग को थोड़ा सा सरल बनाने की कोशिश की, लेकिन यह वास्तव में एक सफलता नहीं थी। इसे सुधारने की कोशिश करेंगे। – tonio

+0

आरेख स्पष्टीकरण के लिए धन्यवाद, यह अब समझ में आता है। – limist

0

कोशिश (सूची एक्स वाई) मुझे यकीन है कि यह आम तुतलाना पर काम करता है हूँ, मैं नहीं जानता कि इस योजना के बारे में

1

मैं चित्र पाया लिस्प सीखते समय Emacs Lisp tutorial विशेष रूप से सहायक में।

1

अरे, मुझे लगता है कि आप इस तरह से इस बारे में सोच सकते हैं;

जब भी एक नहीं के बराबर है, वहाँ कोष्ठक की एक जोड़ी, के रूप में पालन होना चाहिए:

(विपक्ष 1 (विपक्ष 2 शून्य)) -> (सूची 1 2)

(चलो ((एक्स (सूची 1 2 3)) (वाई (सूची 4 5 6)))

1. (विपक्ष xy) -> (विपक्ष (विपक्ष 1 (विपक्ष 2 (विपक्ष 3 शून्य)) (विपक्ष 4 (विपक्ष 5 (विपक्ष 6 शून्य))) यहां, पहला शून्य एक जोड़ी के अंत के लिए खड़ा है जिसे ब्रांडेसिस द्वारा व्यक्त किया जा सकता है; जबकि दूसरी नील पूरी जोड़ी के अंत तक खड़ी होती है जो कि एक और जोड़ी का उपयोग करती है; हां, ((1 2 3) 4 5 6)

2. (सूची xy) -> (विपक्ष एक्स (विपक्ष y शून्य); रूप में हम जानते एक्स एक शून्य होते हैं, तो यह होना चाहिए (1 2 3);

सबसे भीतरी शून्य सबसे बाहरी कोष्ठक अर्थ है, दूसरे भाग दो निल्स, तो ((1 2 3) (4 5 6)) शामिल हैं।

आशा है कि यह मदद कर सकते हैं