2016-04-06 8 views
0

Kurallar, cdr, araba hakkında sahip olduğum en temel kavramı kullanarak bir listeyi tersine çevirmeyi denedim. Burada, l-orig tersine çevrilecek liste ve sayaç olarak l-count davranır.Scheme lisp eksileri ve listesi

(define (rev l-orig l-count) 
(
    if (null? l-count) 
    (cons l-orig '()) 
    (rev (cons (cdr l-orig) (car l-orig)) (cdr l-count)) 
) 
) 
(display (rev '(1 2 3 4 5) '(1 1 1 1 1))) 

Ve çıkış, ben lisp içinde bir acemi ve ben burada basit bir ihtiyaç Dürüst konuşan (((2 3 4 5) . 1)) geçerli:

Kodum buraya. Bu yöntemi kullanmayı düşünürsem, bana doğru bir yöntem önerebilir mi?

+0

ilgili ?: https://stackoverflow.com/questions/19529829/how-to-recursively-reverse-: boş bir akümülatör her zaman geçirmek gerekmez böylece bir yardımcı işlev kullanabilirsiniz a-list-using-basic-operations/19536834 # 19536834 –

cevap

1

Bir biriktirme parametresi yardımıyla kuyruk özyineleme kullanarak bir listeyi ters çevirmeye çalışıyorsunuz. akümülatördür boş listesi şeklinde başlar

(define (rev l-orig l-count) 
    (if (null? l-orig) 
     l-count 
     (rev (cdr l-orig) (cons (car l-orig) l-count)))) 

Bildirim o: en iyi yolu, orijinal listesi ve cons sonunda iade edilecektir akümülatör başında unsurları, her çapraz olacaktır cons için mükemmel ona her yeni eleman ing:

(rev '(1 2 3 4 5) '()) 
=> '(5 4 3 2 1) 
+0

Bu çözüm kolayca kabul edilebilir. Ama benim amacım geri listeyi l-orig'in kendisinde bulmak. Sadece l sayımı sayaç olarak kullanmak istiyorum. Bunun hakkında herhangi bir yardım? –

+0

Yapma. Şemada, girişi değiştirmekten kaçınmaya çalışıyoruz, bunun yerine yeni bir çıktı oluşturmayı tercih ediyoruz, bu da fonksiyonel programlama yoludur. –

0

Oscar'ın cevabı sağda olduğunu.

(define (rev xs) 
    (rev-accum xs '())) 

(define (rev-accum xs accum) 
    (if (null? xs) 
     accum 
     (rev-accum (cdr xs) (cons (car xs) accum))))