2010-11-03 5 views
6

योजना में किसी सूची में फ़ंक्शन क्या है? इसे नेस्टेड सूचियों को संभालने में सक्षम होना चाहिए।एक सूची को रिवर्स कैसे करें?

ताकि यदि आप (reverse '(a (b c d) e)) जैसे कुछ करते हैं तो आपको आउटपुट के रूप में (e (b c d) a) मिल जाएगा।

मुझे इस समस्या से कैसे संपर्क करना चाहिए? मैं सिर्फ एक जवाब की तलाश नहीं कर रहा हूं, लेकिन कुछ ऐसा जो मुझे सीखने में मदद करेगा।

+2

बेहतर जवाब: (परिभाषित करते हैं (rev1 lst) (foldl विपक्ष '() lst)) – wowest

उत्तर

18
(define (reverse1 l) 
    (if (null? l) 
    nil 
    (append (reverse1 (cdr l)) (list (car l))) 
) 
) 

स्पष्टीकरण:

नियम:
1. यदि सूची खाली है, तो रिवर्स सूची भी सूची

के पहले तत्व जोड़ने के खाली
2. किसी और सूची के पीछे पूंछ के पीछे है

इस कोड को इस तरह से देखें:

रिवर्स 1 फ़ंक्शन का नाम है, एल पैरामीटर
है यदि सूची खाली है मुर्गी उलटा भी (सीडीआर एल) के साथ खाली किसी और कॉल reverse1 समारोह जो सूची की पूंछ है और संलग्न है कि पहले alement (कार एल) है कि आप अपने उदाहरण (छद्म कॉड) में एक सूची

के रूप में बनाने के लिए:

1st iteration 
l=>(a (bcd)e) 
car l => a 
cdr l => (bcd)e 
list(car l) =>(a) 
------------------ 
reverse(cdr l)"+"(a) 
------------------ 
2nd iteration 
l=>((bcd)e) 
car l => (bcd) 
cdr l =>e 
list(car l)=>(bcd) 
-------------------- 
reverse(cdr l)"+"((bcd))+(a) 
----------------------- 
3rd iteration 
l=>e 
car l=> e 
cdr l => nil 
list (car l) =>(e) 
------------------------- 
(e (bcd)a) 
+0

ध्यान दें कि यह जवाब कॉमन लिस्प, जो 'nil' का उपयोग करता है में लिखा है ''()' के बजाय। – erjiang

+4

@erjiang जो वास्तव में सच नहीं है - जबकि आम लिस्प 'शून्य' का उपयोग करता है और योजना नहीं है, इस उत्तर के शीर्ष पर परिभाषित फ़ंक्शन वास्तव में योजना है, सामान्य लिस्प नहीं। यद्यपि काम करने के लिए आपको '(परिभाषित करें '()) जैसे कुछ करने की आवश्यकता होगी। – spacemanaki

+0

यह (शून्य के बजाय आइटम वापसी) सिर्फ एक नाबालिग संपादित साथ पूरी तरह से मेरे लिए काम करता: (राजस्व आइटम को परिभाषित() (यदि (शून्य आइटम) आइटम ((राजस्व (सीडीआर आइटम)) (सूची संलग्न (कार आइटम)) ) ) मैं इसे पेटीट चेज़ (http://www.scheme.com/) –

19
(define (my-reverse ls) 
    (define (my-reverse-2 ls acc) 
    (if (null? ls) 
     acc 
     (my-reverse-2 (cdr ls) (cons (car ls)) acc))) 
    (my-reverse-2 ls '())) 

इस सूची में उल्टा करने के लिए, संचायक के सामने से आने वाली सूची और यह consing बंद पहला तत्व लेने एक संचायक चर का उपयोग करता है। यह संचय लेने वाले फ़ंक्शन को छुपाता है और केवल उस सूची को उजागर करता है जो सूची लेता है, इसलिए कॉलर को खाली सूची में पास नहीं होना पड़ता है। यही कारण है कि मेरे पास मेरा रिवर्स -2 है।

(my-reverse-2 '(a (b c d) e) '()); will call 
(my-reverse-2 '((b c d) e) '(a)); which will call 
(my-reverse-2 '(e) '((b c d) a)); which will call 
(my-reverse-2 '() '(e (b c d) a)); which will return 
'(e (b c d) a) 

क्योंकि my-reverse-2 में पिछले समारोह कॉल my-reverse-2 के लिए एक कॉल है, और वापसी मान सही (पहली कॉल की वापसी मान के माध्यम से पारित हो जाता है दूसरा कॉल के रिटर्न मान है, और इतने पर) my-reverse-2पूंछ अनुकूलित है, जिसका अर्थ यह है कि यह ढेर पर कमरे से बाहर नहीं चलेगा। इसलिए जब तक आप चाहें सूची में इसे कॉल करना सुरक्षित है।

आप इसे नेस्टेड सूचियों पर लागू करना चाहते हैं कुछ इस तरह का उपयोग करें:

(define (deep-reverse ls) 
    (define (deep-reverse-2 ls acc) 
    (if (null? ls) 
     acc 
     (if (list? (car ls)) 
      (deep-reverse-2 (cdr ls) (cons (deep-reverse (car ls)) acc)) 
      (deep-reverse-2 (cdr ls) (cons (car ls) acc))))) 
    (deep-reverse-2 ls '())) 

यह अगर तत्व सूची में जोड़ने से पहले एक सूची है देखने के लिए जाँच करता है, और अगर यह है तो पहले पराजयों । चूंकि यह स्वयं को आंतरिक सूची को वापस करने के लिए कहता है, यह मनमाने ढंग से घोंसले को नियंत्रित कर सकता है।

(deep-reverse '(a (b c d) e)) ->'(e (d c b) a) जो विपरीत वर्णमाला क्रम में है, इस तथ्य के बावजूद कि एक नेस्टेड सूची है। यह रूप तो मूल्यांकन करता है: सूची उलट कर
प्रारंभ:

(define (reverse-deep l) 
    (map (lambda (x) (if (list? x) (reverse-deep x) x)) (reverse l))) 

छद्म कोड में स्पष्टीकरण:

(deep-reverse-2 '(a (b c d) e) '()); Which calls 
(deep-reverse-2 '((b c d) e) '(a)) 
(deep-reverse-2 '(e) (cons (deep-reverse-2 '(b c d) '()) '(a))) 
(deep-reverse-2 '(e) (cons (deep-reverse-2 '(c d) '(b)) '(a))) 
(deep-reverse-2 '(e) (cons (deep-reverse-2 '(d) '(c b)) '(a))) 
(deep-reverse-2 '(e) (cons '(d c b) '(a))) 
(deep-reverse-2 '(e) '((d c b) a)) 
(deep-reverse-2 '() '(e (d c b) a)) 
'(e (d c b) a) 
2

यह एक तरीका है कि आप नेस्टेड सूचियों पर लागू होने वाला एक रिवर्स समारोह बना सकते हैं जैसा कि आप आमतौर पर
फिर उल्टा सूची में प्रत्येक तत्व के लिए:
- यदि तत्व स्वयं एक सूची है: प्रक्रिया को पुन: प्रयोजित करें
- वरना: तत्व

0

मत छुओ मैं एक कोड समान प्रकार

(define deep-rev-list 
    (lambda (l) 
    (cond ((null? l) (quote())) 
      ((atom? (car l)) 
      (swap-till-end (carl) (deep-rev-list (cdr l)))) 
      (else 
      (swap-till-end (deep-rev-list (car l)) (deep-rev-list (cdr l))))))) 


(define swap-till-end 
    (lambda (elm lst) 
     (cond ((null? lst) (cons elm '())) 
      (else 
       (cons (car lst) (swap-till-end elm (cdr lst))))))) 

(define atom? 
    (lambda (x) 
    (and (not (null? x)) (not (pair? x))))) 

मैं स्मृति से यह प्रजनन हूँ डालने के लिए इस्तेमाल किया। कुछ त्रुटियां हो सकती हैं। यदि मामला है तो कोड को सही करेगा। लेकिन तकनीक का उपयोग थि लिटिल शेमर में दिए गए नेस्टेड सूचियों के लिए आज्ञाओं के समान है :)। मैं DrRacket में यह जाँच

(गहरे रेव-सूची '((1 2) (3) ((4 5)))) रिटर्न (((5 4)) (3) (2 1))

0

आप बस foldr का उपयोग करके सूची में तत्वों को उल्टा कर सकते हैं:

(foldr (lambda (a r) (append r (list a))) empty lst) 
1

इस रैकेट में एक रिवर्स समारोह जो मैं बहुत कि योजना बेहतर पसंद है। यह केवल मिलान पैटर्न मिलान फ़ंक्शन का उपयोग करता है।

(define/match (rev l) 
    [('()) '()] 
    [((list a ... b)) (cons b (rev a))]) 

> (rev '(a (b c d) e)) 
'(e (b c d) a) 
+1

यह ओ (एन^2) का उपयोग करता है समय और ओ (एन^2) अंतरिक्ष। इस प्रकार सूची जितनी कम हो सकती है उतनी कम संभावना है कि आप कभी भी अपने धैर्य से बाहर निकलने से पहले या आपकी याददाश्त समाप्त होने से पहले जवाब प्राप्त करने जा रहे हैं। – Sylwester

0

मेरे समाधान:

(define (rvrs ls) 
    (if (null? ls) 
    empty 
    (append (rvrs (cdr ls)) (cons (car ls) empty))))