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 :

Petit programme qui trouve un caractère.


Sujet :

Python

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    64
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 64
    Points : 26
    Points
    26
    Par défaut Petit programme qui trouve un caractère.
    Bonjour

    Je dois faire un petit programme qui cherche un caractère donné dans une chaine de caractères.

    Donc une fonction qui attend 2 arguments..

    Donc une fonction "trouve" ==> def trouve()

    et quand je fais print trouve("Juliette & Roméo", "&")

    il doit m'indiquer 9.. POur dire que le "&" se trouve en 9ème position...

    Je peux seulement utiliser les IF et FOR.. pas de boucle While..

    Merci beaucoup

  2. #2
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 222
    Points : 290
    Points
    290
    Par défaut
    Il suffit d'itérer ta chaine de caractère dans une boucle for. La fonction enumerate peut être utile dans ton cas car une retourne la position du caractère:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    # -*- coding: utf-8 -*-
    def trouve(chaine, caract):
        for i, c in enumerate(chaine):
            if c == caract:
                return i
     
    print trouve("Juliette & Roméo", "&")
    Une méthode est déjà implémentée dans python:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    # -*- coding: utf-8 -*-
    print "Juliette & Roméo".find("&")
    Si tu utilises python 3 pense à rajouter des parenthèse aux print

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    64
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 64
    Points : 26
    Points
    26
    Par défaut
    Merci

    Le .find j'y avais pensé mais le prof ne veut pas qu'on utilise enumerate et .find

    Donc...

    Voilà comment moi j'ai fait avec une boucle.. Mais je peux plus utiliser le while..

    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
     
     
    # -*- coding: cp1252 -*-
     
    def trouve(chaine, caract):
     
        cpt=0
     
        while cpt < len(chaine):
            if chaine[cpt]==caract:
                return cpt
            cpt+=1
        return "Le caractère recherché n'est pas dans la phrase !" #ce qu'il indique lorsque le caract recherché n'est pas présent
     
    print trouve("Juliette & Roméo", "&")

  4. #4
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Citation Envoyé par tonykart13 Voir le message
    Le .find j'y avais pensé mais le prof ne veut pas qu'on utilise enumerate et .find

    Donc...

    Voilà comment moi j'ai fait avec une boucle.. Mais je peux plus utiliser le while..
    Drôlement limitatif ton prof.

    Et avec cela ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    >>> def trouve(chaine, caract):
    ...     start, end=chaine.split(caract)
    ...     return len(start)
    ... 
    >>> print trouve("Juliette & Roméo", "&")
    9
    >>>
    @+
    Merci d'utiliser le forum pour les questions techniques.

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    64
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 64
    Points : 26
    Points
    26
    Par défaut
    Merci encore une fois...

    Mais je peux seulement utiliser un FOR ou IF pas des fonctions que Python propose...

    C'Est sa le problème...

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 222
    Points : 290
    Points
    290
    Par défaut
    Je pense que ton prof veut un truck dans le genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    # -*- coding: utf-8 -*-
     
    def trouve(chaine, caract):
        for i in range(len(chaine)):
            if chaine[i] == caract:
                return i
     
        return "Le caractère recherché n'est pas dans la phrase !"
     
    print trouve("Juliette & Roméo", "&")

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2010
    Messages : 53
    Points : 64
    Points
    64
    Par défaut
    petite remarque. nyko77 a écrit la fonction que ton prof attend, mais il vaudrait mieux renvoyer des entiers dans tous les cas. En général on renvoie -1 si le caractère n'est pas dans la chaine.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # -*- coding: utf-8 -*-
     
    # je modifie un tout petit peu le code de nyko77
    def trouve(chaine, caract):
        index = -1
        for i in range(len(chaine)):
            if chaine[i] == caract:
                index = -1
                break
        return index
     
    print trouve("Juliette & Roméo", "&")

  8. #8
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 222
    Points : 290
    Points
    290
    Par défaut
    petite remarque. nyko77 a écrit la fonction que ton prof attend, mais il vaudrait mieux renvoyer des entiers dans tous les cas. En général on renvoie -1 si le caractère n'est pas dans la chaine.
    Je suis d'accord. Ou on peut également faire ainsi, en réutilisant mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    # -*- coding: utf-8 -*-
     
    def trouve(chaine, caract):
        for i in range(len(chaine)):
            if chaine[i] == caract:
                return i
     
        return -1
     
    print trouve("Juliette & Roméo", "&")

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2010
    Messages : 53
    Points : 64
    Points
    64
    Par défaut
    c'est pas que je veux avoir le dernier mot, mais .... Le code de nyko77 est parfait (c'est ce que j'écrirais). Mais si le prof n'aime pas les return au milieu des boucles, ... (alors j'ai gagné )

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    64
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 64
    Points : 26
    Points
    26
    Par défaut
    merci

    mais que veut dire le in ran(len(chaine)) ??

    Je n'ai jamais vu et j'aimerais un petite explication

    Grand merci

  11. #11
    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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    # -*- coding: utf-8 -*-
     
    # je modifie un tout petit peu le code de nyko77
    def trouve(chaine, caract):
        index = -1
        for i in range(len(chaine)):
            if chaine[i] == caract:
                index = i
                break
        return index
     
    print trouve("Juliette & Roméo", "&")
    Le prof sera plus serein comme ça.

    Pffrr, il aura fallut s'y mettre à trois.

    vincent

  12. #12
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 222
    Points : 290
    Points
    290
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mais que veut dire le in ran(len(chaine)) ??
    Le range(x) retourne une liste de 0 à x-1:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    >>> print range(5)
    [0, 1, 2, 3, 4]
    donc avec un for:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    >>>for x in range(5):
    ...     print x
    ... 
    0
    1
    2
    3
    4
    si tu mets len(chaine) à la place de 5, ça fait une boucle de 0 jusqu'au nombre de caractère.

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    64
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 64
    Points : 26
    Points
    26
    Par défaut
    Voilà

    J'ai trouver le moyen le plus facil sans utiliser les options que Python connais

    tout simple ! Mais je me suis cassé la tête 1heure.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    def trouve(chaine, caract):
     
     
        cpt=0
        for carac in chaine:                                       
            if carac==caract:                                     
                return cpt                                       
            cpt+=1
        return -1
     
    rep=trouve("Juliette & Roméo", "&")
     
    print rep
    Un grand merci quand même pour vo idées

  14. #14
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    sans utiliser les options que Python connais
    Ce ne sont pas des options, c’est même tout le contraire d’options puisque ce sont des fonctions livrées en série dans Python, ce sont les “built-in“ fonctions. Il est difficile de traduire “built-in“: prédéfinie, de cœur, encastrée, intégrée, de base, de série, préimportée, préinstallée ..... ?

    ---------------------------------------


    Ah ! tu as trouvé toi même la fonction que j’ai écrite aussi, en y mettant le moins possible de fonctions prédéfinies du langage, et que voici.
    trv_nue() ne comporte même pas len() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def trv_nue(ch, car, cpt=-1):
        for c in ch:
            cpt = cpt + 1
            if c==car: return cpt
        return -1
    J’ai repris ta variable cpt. Mais appeler carac et caract deux références, qui plus est à comparer, ce n’est pas une bonne pratique.

    La mise en paramètre de cpt et sa prise implicite de -1 comme argument permettent de diminuer d’une ligne.

    C’est bien d’avoir trouvé ça tout seul car c’est une pratique très pythonienne: la possibilité d’itérer sur les objets et pas seulement sur leurs indices.




    J’ai aussi cherché une fonction avec le moins de lignes possible.

    trv_recurs() en 4 lignes, comme trv_enum() et trv_xrange() , mais elle n’est pas vraiment concise ni facilement compréhensible:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def trv_recurs(chaine, car, z=0):
        if z<len(chaine)-1 and chaine[z]!=car: return trv_recurs(chaine,car,z+1)
        if z<len(chaine) and chaine[z]==car: return z
        return -1






    J’ai comparé les vitesses des différentes fonctions.



    Toutes les fonctions, sauf trv_find() , doivent comporter return -1 comme dernière instruction au cas où le caractère recherché n’est pas dans la chaîne (ce qui inclut le cas de la chaîne vide).



    La fonction de PauseKawa avec split() est astucieuse mais nécessite d’être modifiée sinon start,end = chaine.split(car)
    • ne peut pas dépaqueter chaine.split(car) dans un couple start,end quand le caractère recherché se trouve plus d’une fois dans la chaîne
    • ou produit une erreur quand il ne s’y trouve pas du tout.



    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    from time import clock
     
    def trv_find(ch, car):
        return ch.find(car)
     
    def trv_split(ch, car):
        try:
            start,end = ch.split(car,1)
            return len(start)
        except:
            return -1
     
    def trv_xrange(ch, car):
        for i in xrange(len(ch)):
            if ch[i] == car: return i
        return -1
     
    def trv_nue(ch, car, cnt=-1):
        for c in ch:
            cnt = cnt + 1
            if c==car: return cnt
        return -1
     
    def trv_enum(ch, car):
        for i,c in enumerate(ch):
            if c == car: return i
        return -1
     
    def trv_len(ch, car, rec=''):
        for c in ch:
            rec = rec + c
            if c==car: return len(rec)-1
        return -1
     
    def trv_recurs(ch, car, z=0):
        if  z<len(ch)-1 and ch[z]!=car: return trv_recurs(ch,car,z+1)
        if  z<len(ch)   and ch[z]==car: return z
        return -1
     
     
    for name in ('trv_find', 'trv_split', 'trv_xrange',
                 'trv_nue', 'trv_enum', 'trv_len', 'trv_recurs'):
        f = globals()[name]
        print name.rjust(12),'  ',
        for ch in ('phenylglycyl-cysteinyl-tyrosine','fleur',''):
            print f(ch,'y'),'\t',
        print
    print
     
     
    iterat = 1000
     
    for i in xrange(iterat):
        li = []
        te = clock()
        for j in xrange(100):
            x = 'jhehcweifiweggichbeidgcieyfchbhcgeyddgceygqhwb'.find('q') # ....qhwb
        tf = clock()
        li.append(tf-te)
    print 'find'.rjust(12)+'  '+str(min(li)).ljust(20)+str(x)
     
    for name in ('trv_find', 'trv_split', 'trv_xrange',
                 'trv_nue', 'trv_enum', 'trv_len', 'trv_recurs'):
        f,li = globals()[name],[]
        for i in xrange(iterat):
            te = clock()
            for j in xrange(100):
                x = f('jhehcweifiweggichbeidgcieyfchbhcgeyddgceygqhwb','q') # ....qhwb
            tf = clock()
            li.append(tf-te)
        print name.rjust(12)+'  '+str(min(li)).ljust(20)+str(x)

    La hiérarchie des fonctions par temps croissant est la suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
            find  0,73
        trv_find  1
       trv_split  2,27
      trv_xrange  11,4
         trv_nue  11,8
        trv_enum  12,2     
         trv_len  14
      trv_recurs  35
    Pour comparer valablement, j’ai mis find() dans une fonction trv_find() .
    find() seule prend effectivement 27 % de temps en moins que find() dans une fonction trv_find() .

    trv_find() est de loin la plus rapide de toutes: find() est une méthode extrêmement rapide.



    trv_split() = pas mal : 2,3 fois plus longue que trv_find() mais la suivante est à 11 fois. C’est sans doute parce que split() doit utiliser l’algorithme de find() pour trouver le caractère avant de faire la découpe.



    Toutes les autres fonctions sont plus de 10 fois plus lentes.
    Aucune surprise à voir la fonction récursive trv_recurs() être encore 3 fois plus lente que ces dernières: la récursivité rend les fonctions plus longues.

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2010
    Messages : 53
    Points : 64
    Points
    64
    Par défaut
    Yep!

    Si le caractère cherché est dans la chaine, alors on peut écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    start, end = chaine.split(car, 1)
    #exemple:
    print "hello world".split('o', 1)
    # affiche: ['hell', 'world']
    De manière plus générale, s.split(sub, n) agit comme split mais ne coupe la chaine qu'en n morceaux. Dans ce cas-ci, start contient bien le début de la chaine jusqu'au caractère précédent la première occurence de car.
    On pourrait écrire (en condensé)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def mon_find(s, c):
        if not c in s:
            return -1
        else:
            return len(s.split(c, 1)[0])
    Pour info, j'ai lancé le code de eyquem pour mesurer la vitesse de la fonction ci-dessus et elle est juste un peu plus rapide que trv_split. Son temps: à peu près 96% du temps de trv_find.

Discussions similaires

  1. [Turbo Pascal] Ecrire un programme qui lit une chaîne de caractères
    Par agan2012 dans le forum Turbo Pascal
    Réponses: 9
    Dernier message: 22/02/2009, 20h46
  2. Comment changer le petit image qui se trouve dans la barre d'adresse.
    Par P_mission dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 10/07/2008, 16h19
  3. Réponses: 8
    Dernier message: 04/03/2008, 23h30
  4. Petits programmes qui m'ennuie au démarrage
    Par Ganak dans le forum Windows XP
    Réponses: 1
    Dernier message: 05/02/2007, 19h36
  5. Petit programme qui pompe 50% de CPU
    Par nicofromChina dans le forum Langage
    Réponses: 6
    Dernier message: 16/01/2007, 11h03

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