2017-04-30 1 views
1

Je suis tout à fait nouveau dans le langage de programmation Scheme et je n'arrive pas à comprendre la différence entre ces deux morceaux de code, en particulier les lignes que j'ai indiquées.Schéma null? instruction

;program that returns the Nth element in a list where N is an integer argument 

(define getElement 
(lambda (N L) 
(cond 
    ((null? L) '()) 
    ((= N 1) (car L)) 
    (#t(getElement (- N 1) (cdr L)));this line 
) 
) 
) 

;takes a list L and a number N and returns the list L but with the first N elements removed 
(define remove 
(lambda (N L) 
(cond 
    ((null? L) '()) 
    ((= N 0) L) 
    (#t(remove (- N 1) (cdr L)));and this line 
) 
) 
) 

Pourquoi la sortie de ces programmes est-elle si différente? Je ne peux pas voir quel impact les 2 lignes après l'instruction de condition ont sur la sortie des programmes autre que vérifier si la liste est vide et si l'entier N est une certaine valeur, faites ceci.

Ceci est mon premier poste si des conseils sont les bienvenus

Répondre

2

Les deux fonctions sont récursives et utilisent la même stratégie de récursivité. Cependant, ils font des choses très différentes quand vous arrivez au fond de la récursivité. Chaque fonction réduit n par un et réduit la liste d'un élément, en l'appelant dans le nouveau contexte. Ainsi, la liste (au moins représentée dans les arguments des fonctions) devient de plus en plus courte dans les deux cas. La fonction remove renvoie la totalité de la liste restante. Comme un certain nombre d'éléments ont déjà été supprimés de la copie de la liste dans l'argument de la fonction remove, cela a pour effet de renvoyer une liste raccourcie. Cependant, la fonction nth-element ne retourne pas la liste; il retourne (voiture l), ou retourne l'élément dans la cellule cons contenue dans l. C'est-à-dire qu'il ne renvoie que l'élément actuel de la liste. C'est pourquoi ils produisent des résultats différents.

0

Les lignes que vous avez indiquées font la même chose. Absolument aucune différence! Il se recurses à lui-même avec l'index réduit et la liste a changé à cdr.

Lorsque le scénario de base rencontre le premier renvoie le premier élément et le second renvoie la liste.

(getElement 1 '(1 2 3)) ; ==> 1, Since it does (car L) 
(remove 0 '(1 2 3))  ; ==> (1 2 3), since it does L 

Maintenant, si votre getElement a travaillé comme list-ref0 aurait dû être le cas de base, le même que remove. En outre, il devrait signaler une erreur lorsque la liste est vide avant que l'index est zéro. Ceci est plus semblable:

#!r6rs 
(import (rnrs)) 
(define (my-list-ref lst pos) 
    (cond ((null? lst) (raise 'list-too-short)) 
     ((zero? pos) (car lst)) 
     (else (my-list-ref (cdr lst) (- pos 1))))) 

(my-list-ref '() 1) 
; ==> uncaught exception: list-too-short 
1

Comme vous le dites,

si l'entier N est une certaine valeur, faire

et la différence est dans le « faire » .

Le premier,

((= N 1) (car L)) 

dit « pour obtenir le premier élément d'une liste, prendre la car de la liste ».

Le second,

((= N 0) L) 

dit "pour supprimer aucun élément dans une liste, retourner la liste entière".

Les récurrences regardent exactement le même, mais le premier lit « obtenir élément N - 1 de la cdr de la liste », tandis que le second lit « retirer N - 1 éléments du cdr de la liste ».

(Il semble que la première fonction a été traduit de Lisp, où nil est "faux-y". Une fonction plus Scheme-y retournerait #f.)