IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

recherche dichotomique entiers


Sujet :

Python

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 10
    Points : 5
    Points
    5
    Par défaut recherche dichotomique entiers
    Bonjour,

    J'essaie de programmer un algorithme de recherche dichotomique dans une liste d'entiers :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    maliste = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
     
    def rech_dichot(liste, borne_inf, borne_sup, x):
     
    	borne_interm = (borne_sup + borne_inf)/2;
     
     
    	if liste[borne_sup] < x or liste[borne_inf] > x: #si l'entier recherche n'est pas dans la liste
    		return False;
    	if liste[borne_interm] == x:
    		return True;
    	else:
     
    		if maliste[borne_interm] > x:
    			rech_dichot(liste, borne_inf, borne_interm-1, x);
    		else:
    			if maliste[borne_interm] < x:
    				rech_dichot(liste, borne_interm + 1, borne_sup, x);
    			else:
    				return False;
     
     
    nbre_rech = input("Veuillez rentrer l'entier recherche : ");
     
    print rech_dichot(maliste, 0, len(maliste)-1, int(nbre_rech));
    J'ai utilisé une fonction recursive, je pense avoir optimisé pas mal le code, mais si vous voyez une amélioration possible n'hésitez pas à me le signaler.

    Le problème c'est que si je rentre l'entier 2 par ex dans la console, la fonction me renvoie "none" alors que si je rentre l'entier 10 elle me renvoie "True". J'ai bien cherché mais je ne voit pas d'où ça peut venir. Pourriez-vous me mettre sur la voie svp ?

    Merci

  2. #2
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Salut,

    On suppose que tu ne peux pas faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    print x in maliste
    Le problème de ton code c'est que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    	if liste[borne_interm] == x:
    		return True
    1.- borne_interm n'est pas un entier dans un très grand nombre de cas ;

    2.- le return ne renvoie pas à l'appel initial de la fonction mais à l'appel récursif qui se poursuit jusqu'à épuisement des nombres de la liste.

    Dans ta liste, seul le nombre 10 est trouvé tout de suite (borne_intrem == 10) et dans ce cas le return renvoie à l'appel initial.

    Tu peux aussi simplifier ta manipulation de liste.

    exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    maliste = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
     
    def rech_dichot(l, x):
        is_present = False
        if x < l[0] or x > l[-1]:
            return False
     
        while 1:
            mid = int(l[0] + ((l[-1] - l[0]) / 2))
            if x == mid:
                is_present = True
                break
            elif x > mid:
                l = [n for n in l if n >= mid]
            else:
                l = [n for n in l if n <= mid]
            if len(l) < 3:
                is_present =  x in l
                break
            else:
                rech_dichot(l, x)
     
        return is_present
     
     
    for i in maliste:
        print "%s in maliste  : %s" % (i, rech_dichot(maliste, i))
    Devrait être encore simplifié mais il est tard.

  3. #3
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Il est intéressant d'examiner le code du module bisect.py livré avec Python.

    Voir aussi mon tuto comme source d'inspiration: j'ai fait une fonction de recherche par dichotomie qui utilise les mêmes fonctions comp et key que la méthode sort() et la fonction sorted():

    http://python.jpvweb.com/mesrecettes...?id=dichotomie

    Tyrtamos
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    Je vous remercie beaucoup je vais étudier ça ce soir, je vous tien au courant

  5. #5
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Bonjour.

    Un petit conseil rapide à Joe_Dupont.

    Au lieu du code suivant...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    	if liste[borne_sup] < x or liste[borne_inf] > x: #si l'entier recherche n'est pas dans la liste
    		return False;
    	if liste[borne_interm] == x:
    		return True;
    	else:
    		...
    ..., tu devrais utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	if liste[borne_inf] <= x <= liste[borne_sup]:
    		Tu tries...
    	else:
    		return False
    Personnellement, j'utiliserais même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	if liste[borne_inf] <= x <= liste[borne_sup]:
    		Tu tries et renvoie True si cela marche et rien sinon.
     
    	return False
    Autre remarque : les points-virgules en fin de ligne ne servent à rien !

Discussions similaires

  1. probleme : recherche dichotomique
    Par M.a.n.u. dans le forum C
    Réponses: 3
    Dernier message: 17/06/2006, 23h30
  2. recherche dichotomique sur chaînes de carctères
    Par contexte dans le forum Langage
    Réponses: 4
    Dernier message: 13/04/2006, 00h31
  3. Réponses: 23
    Dernier message: 10/01/2006, 13h33
  4. Recherche dichotomique
    Par remixtech dans le forum C
    Réponses: 4
    Dernier message: 06/01/2006, 18h39
  5. Recherche dichotomique
    Par Gryzzly dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 31/12/2005, 11h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo