Liste n-uplet en Scheme

Résolu
Freaks -  
 Freaks -
Bonjour,

J'ai un exercice sur les listes n-uplet mais je bloque sur mon programme:s


- Donner une définition de la fonction N-max dont la spécification est:

;;; N-max: LISTE[NUPLET[String Nombre Nombre]] -> NUPLET[String Nombre Nombre]
;;; (N-max L) renvoie le premier n-uplet de la liste L qui a le plus grand deuxième élément.
;;; HYPOTHÈSE: L est non vide.


Mon programme:

(define (N-max L)
(if (pair? L)
(if (> (car (cdr (car L)) (car (cdr (car (cdr L)))))
(cons (car L) (cdr (cdr L)))
(
)
)

Exemple test:

(N-max '(("bob" 2 10) ("leo" 12 13) ("bea" 15 13) ("luc" 4 9) ("eve" 15 16) ("jo" 14 11))) -> ("bea" 15 13)


En fait, ce que je veux faire c'est de comparer le deuxième élément des deux premiers sous-liste et garder le sous-liste dont le deuxième élément est le plus grand et de faire ça pour les n- sous-liste. J'ai essayé d'utiliser la fonction prédéfinis max pour qui rend le maximum des arguments mais j'ai pas réussi...

Pouvez-vous m'éclaircir un peu sur comment m'y prendre, s'il vous plait ?
Merci d'avance.

A voir également:

6 réponses

Freaks
 
Up.

(define (N-max L)
(if (pair? (car L))
(if (< (car (cdr (car L))) (car (cdr (car (cdr L)))))
(N-max (cons (cadr L) (cdr (cdr L))))
(N-max (cdr L)))
)
)

J'ai fais ce programme mais j'ai un message d'erreur au niveau du gras.
Ca dit: "car: expects argument of type <pair>; given ()"

Je ne comprend pas trop pourquoi ça affiche ça...
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
L=(("bob" 2 10) ("leo" 12 13) ... ("jo" 14 11))

(car L) = ("bob" 2 10)
(cdr (car L)) = (2 10)
(car (cdr (car L))) = 2 

(cdr L)=(("leo" 12 13) ... ("jo" 14 11))
(car (cdr L)) = ("leo" 12 13)
(cdr (car (cdr L))) = (12 13)
(car (cdr (car (cdr L)))) = 12

Pas de problème, tu as bien ce que tu veux, sauf qu'après tu appelles (N-max (cdr L)) donc L diminue au fur et à mesure :

L=(("jo" 14 11))

(car L) = ("jo" 14 11)
(cdr (car L)) = (14 11)
(car (cdr (car L))) = 14 

(cdr L)=()
(car (cdr L)) = "car: expects argument of type <pair>; given ()"

Il faut que tu utilises un test (if (null (cdr L))) pour prendre en compte ce dernier cas.

Remarque :
Tu peux utiliser (trace N-max) pour consulter les appels successifs de N-max
Pour annuler le traçage : (untrace N-max)
0
Freaks
 
Vu que j'arrivais pas à faire, j'ai essayer d'utiliser un autre define dans le define:

(define (N-max L)
(define (N-max2 L)
(if (pair? L)
(max (car (cdr (car L))) (N-max2 (cdr L)))
0))
(if (= (car (cdr (car L))) (N-max2 L))
(car L)
(N-max (cdr L))))

Avec ça, ça marche j'ai essayer plusieurs méthode et ça marchait.

Sinon, si je souhaite par exemple obtenir le dernier n-uplet de la liste dont le 2e élément est le plus grand au lieu du premier n-uplet, que dois-je faire ?

Merci, pour ta réponse, je vais essayer de trouver aussi avec ce que tu m'as dit.
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
Voici comment je ferais (en Common Lisp, je te laisse le convertir en Scheme)

(defun nmax (l)
(
	(if	(null (cdr l))
		(car l)
		(nmax	(cons 	(if	(> (cadar l) (cadadr l))
					(car l)
					(cadr l)
				)
				(cddr l)
)	)	)	)

(nmax '(("a" 1 1) ("b" 2 1) ("c" 2 2))) ;  --> ("c" 2 2)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Freaks
 
Ahh je te remercie, j'ai réussi à le traduire en scheme. Je savais pas, par contre, qu'on pouvait introduire un if dans le cons

Sinon, à partir de ton programme, quel serait le résultat si tu voulais prendre le 1er n-uplet dont le 2e élément est le plus grand ? (Il devrait y avoir pas beaucoup de différence... )

Je te remercie pour ton temps passé à m'aider.
Cordialement, Freaks.
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
Effectivement il y aurait peu de différence, il suffirait de remplacer > par >=

Pour le if dans le cons, c'est "évident", if retourne toujours une valeur, soit celle du "then", soit celle du "else" donc ça ne pose pas de problème.

J'aurais pu faire (nmax (if (...) (cons ...) (cons ...))), if aurait donc pris la valeur d'un des deux cons, mais ça aurait nécessité de répéter les cons alors que le deuxième paramètre est le même.
J'ai donc préféré faire (nmax (cons (if ...) ...)) pour éviter cette répétition...
0
Freaks
 
Ah okay, je vois, merci encore.

Une toute petite dernière chose, tu ne saurais pas quel serait le changement à faire pour avoir le dernier n-uplet dont le 2e élément est le plus grand au lieu du premier dans mon programme ? Je cherche, je cherche mais je vois pas trop ou ?! :s
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
C'est le code que j'ai déjà fait ça !

Si tu mets > (comme moi) tu auras le dernier n-uplet dont le 2 élément est le plus grand.
Si tu mets >= tu auras le premier n-uplet dont le 2 élément est le plus grand.
0
Freaks
 
Avec mon programme:

(define (N-max L)
(define (N-max2 L)
(if (pair? L)
(max (car (cdr (car L))) (N-max2 (cdr L)))
0))
(if (= (car (cdr (car L))) (N-max2 L))
(car L)
(N-max (cdr L)))) 



Ca marche pas de la même manière que le tien. Vu que j'ai fais avec un = que je met > ou >= ça donne pas le même résultat..
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
Ton code souffre d'un gros problème de complexité, à chaque fois que tu appelles N-max, tu recalcules N-max2, du coup pour une liste de taille N, tu fais O(N²) calculs, quand je n'en fais que O(N). En plus c'est assez compliqué à relire...

Néanmoins, si tu veux continuer sur le code que tu as fait, il faut que tu enlève l'imbrication N-max et N-max2, à peu près comme ceci (je n'ai pas vérifié) :

(define (N-max2 L)  
	(if	(pair? L)  
		(max (car (cdr (car L))) (N-max2 (cdr L)))  
		0  
)	)  

(define (N-max3 L M L2)  
	(if 	(pair? L)  
		(if	(= (car (cdr (car L))) M)  
			(N-max3 (cdr L) M (car L)) ; ou (car L) 
			(N-max3 (cdr L) M L2)  
		)  
		L2  
)	)  

(define (N-max L)  
	(N-max3 L (N-max2 L) ())  
)

La confiance n'exclut pas le contrôle
0
Freaks
 
Ah je comprend... Ton programme fonctionne ! Merci.
Je voudrais savoir les éléments de N-max3, L, M et L2 correspond à des liste ?
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
L c'est la liste de départ, M c'est le maximum que tu calcules avec N-max2, et L2 c'est le dernier résultat connu dont le maximum est M, ce qui permet d'en récupérer LE dernier.
0
Freaks
 
Okay, je te remercie pour ton aide, et ton temps passé pour m'aider.

Merci encore,
Cordialement, Freaks.
0