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

Lisp Discussion :

fonction qui repère n fois


Sujet :

Lisp

  1. #1
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2014
    Messages : 208
    Points : 60
    Points
    60
    Par défaut fonction qui repère n fois
    Bonsoir,

    Je bloque pour écrire une fonction qui repère combien de fois une chaîne est inclue dans une autre.

    (string-contain 'ark' 'abbbe) => 0
    (stringcontain 'ark' 'ddarkdark) => 2

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    (defun string-contain (string1 string2)
      (cond
       ((not (length string1)) nil) ; string1 est vide (pas besoin de le tester à chaque fois)
       ((> (length string1) (length string2)) nil) ; string1 est plus longue que chaine2
       ((string= string1 (subseq string2 0 (length string1))) string1) 
       (t (+ 1(string-contain string1 (subseq string2 1))))))
    Mais le code ne marche pas :s

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *** - +: "ark" is not a number

    Merci

  2. #2
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par l1informatique Voir le message
    Bonsoir,

    Je bloque pour écrire une fonction qui repère combien de fois une chaîne est inclue dans une autre.

    (string-contain 'ark' 'abbbe) => 0
    (stringcontain 'ark' 'ddarkdark) => 2

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    (defun string-contain (string1 string2)
      (cond
       ((not (length string1)) nil) ; string1 est vide (pas besoin de le tester à chaque fois)
       ((> (length string1) (length string2)) nil) ; string1 est plus longue que chaine2
       ((string= string1 (subseq string2 0 (length string1))) string1) 
       (t (+ 1(string-contain string1 (subseq string2 1))))))
    Mais le code ne marche pas :s

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *** - +: "ark" is not a number

    Merci
    C'est normal tu renvoies string1 si elle est trouvée dans string2 et tu lui rajoutes 1 si elle n'est pas trouvée. Mais le problème zst plus grave que ça: la condition 3 devrait être remplacée par 1+ recursion et la 4 par une recursion simple
    Bon lisp!

  3. #3
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2014
    Messages : 208
    Points : 60
    Points
    60
    Par défaut
    J'ai refais une autres mais il marche que si il s'agit des mêmes chaines de caractères

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    (defun string-contain (string1 string2)
      (cond  
        ((> (length string1) (length string2)) 0)
        ((and (= (length string1) (length string2)) (string= string1 string2)) 1)
        ((string= string1 (subseq string2 0 (length string1)))
        (1+ (string-contain string1 (subseq string2 (length string1))))) (t 0)))
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    (string-contain "abc" "abcabcabc")
    3
    mais si c'est autres choses non comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    (string-contain "abc" "ddabccabcabcdd")
    0

  4. #4
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    tu ne réfléchis pas avant de coder, ce n'est pas bien ;-)

    pour une fonction récursive, il faut un cas 0 et un cas n+1 exprimé à partir de n:

    cas 0: tu l'as bien trouvé, il s'agit de
    (< (length str1) (length str2)) ==> on retourne 0

    cas n+1 = (if (string= str1 (subseq str2 0 (length str1))) (1+ cas-n) cas-n)

    sachant que le cas n est (string-contain str1 (subseq str2 1))

    A toi de mettre tout ça en ordre!

  5. #5
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2014
    Messages : 208
    Points : 60
    Points
    60
    Par défaut
    Bonjour,

    J'ai suivi vos conseil mais ça ne marche toujours pas, pourtant ça l'aire logique

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    (defun string-contain (string1 string2)
      (cond  
        ((> (length string1) (length string2)) 0)
        ((and (= (length string1) (length string2)) (string= string1 string2)) 1)
        ((string= string1 (subseq string2 0 (length string1))) 
        (1+ (string-contain string1 (subseq string2 1)))  (string-contain string1 (subseq string2 1)))))
    merci

  6. #6
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    Dans ton cas, cond n'est pas l'idéal, parce-qu'il y a deux choix successifs et que le deuxième dépend du premier:

    Soit len(str1) < len(str2) et on en a fini,
    soit non et on calcule string-contains str1 subseq(str2, 1) auquel on ajoute:
    soit 1 si str2 commence par str1,
    soit 0

    Un exemple d'implémentation serait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    (defun string-contains (str1 str2)
      (if (> (length str1) (length str2))
          0 ;; on est arrivés à la fin
          (let ((cas_n-1 (string-contains str1 (subseq str2 1)))) ;; on calcule le cas n-1
    	(if (string= str1 (subseq str2 0 (length str1))) ;; et on y ajoute
    	    (1+ cas_n-1) ;; soit 1 si str2 commence par str1
    	    cas_n-1)))) ;; soit 0

  7. #7
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2014
    Messages : 208
    Points : 60
    Points
    60
    Par défaut
    Ça me donne toujours la meme erreur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [168]>     (defun string-contains (str1 str2)
         (if (> (length string1) (length string2)) 0
          (let 
          ((string-contain str1 (subseq str2 1)) (string-contains str1 (subseq str2 1))) 
          (if (string= str1 (subseq str2 0 (length str1))) 
          (1+ (string-contain str1 (subseq str2 1))) (string-contain str1 (subseq str2 1))))))
    string-contains
    [169]> (string-contain "abc" "abcabc")
     
    *** - 1+: nil is not a number
    Rentrées possibles:
    USE-VALUE      :R1      Input a value to be used instead.
    ABORT          :R2      Abort main loop
    Break 1 [170]>

  8. #8
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    Mmmm... ton code est différent de celui que je t'ai proposé (que j'ai testé gracieusement) et tu as rajouté quelques erreurs.
    let est une macro qui permet de définir une variable locale (la variable n'existe que dans la portée de let):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (let ((variable valeur-de-la-variable))
      (on peut utiliser la variable))
    on ne peut plus utiliser la variable
    Je pense que ton code n'est correct que par accident...

  9. #9
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2014
    Messages : 208
    Points : 60
    Points
    60
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    (defun string-contains (str1 str2)
         (if (> (length string1) (length string2)) 0
          (let 
          ((string-contain str1 (subseq str2 1)) (string-contains str1 (subseq str2 1))) 
          (if (string= str1 (subseq str2 0 (length str1)))
          (1+ (string-contain str1 (subseq str2 1)))) (string-contain str1 (subseq str2 1)))))

    toujours pas

  10. #10
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    Oui mais encore un code différent.

    (let ((string-contain str1 (subseq str2 1)) (string-contains str1 (subseq str2 1)))

    N'a pas de sens

  11. #11
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2014
    Messages : 208
    Points : 60
    Points
    60
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    (defun string-contains (str1 str2)
         (if (> (length string1) (length string2)) 0
          (let 
          ((string= str1 (subseq str2 0 (length str1))) (string-contain str1 (subseq str2 1))) (string-contains str1 (subseq str2 1))) 
          (if (string= str1 (subseq str2 0 (length str1)))
          (1+ (string-contain str1 (subseq str2 1)))) (string-contain str1 (subseq str2 1))))
    Et la c'est toujours le let le problème ??

    Franchement on n'a pas étudier let on peut la remplacer pat setq ??

  12. #12
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    oui c'est toujours let le problème!

    La syntaxe de let n'est pourtant pas si compliquée et je t'ai donné un exemple dans un de mes messages.

    Mais tu peux faire sans, tu vas juste te répéter:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (defun string-contain (str1 str2)
      (cond
        ((> (length str1) (length str2)) 0)
        ((string= str1 (subseq str2 0 (length str1))) (1+ (string-contain str1 (subseq str2 1))))
        (T (string-contain str1 (subseq str2 1)))))
    let te permet de créer une variable locale (au contraire de setq) pour éviter de te répéter:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    (let ((next (string-contain str1 (subseq str2 1))))
      (if (string= str1 (subseq str2 0 (length str1)))
        (1+ next)
        next))
    Prends de l'avance sur tes cours, cherche des choses sur Internet, regarde les livres gratuits sur LISP, il y en a de très biens!

  13. #13
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2014
    Messages : 208
    Points : 60
    Points
    60
    Par défaut
    Merci beaucoup j'ai compris

  14. #14
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par stendhal666 Voir le message
    Mais tu peux faire sans, tu vas juste te répéter:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (defun string-contain (str1 str2)
      (cond
        ((> (length str1) (length str2)) 0)
        ((string= str1 (subseq str2 0 (length str1))) (1+ (string-contain str1 (subseq str2 1))))
        (T (string-contain str1 (subseq str2 1)))))
    let te permet de créer une variable locale (au contraire de setq) pour éviter de te répéter:
    Pour éviter de se répéter, on peut aussi utiliser le retour du "if" (au prix d'une addition de 0 et d'une perte de récursivité terminale):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (defun string-contain (str1 str2)
      (if (> (length str1) (length str2))
          0
        (+ (if (string= str1 (subseq str2 0 (length str1))) 1 0)
           (string-contain str1 (subseq str2 1)))))
    Cela dit, il peut être important de noter que ce code, qui est équivalent au précédent, comporte un petit bug!

    Comme très souvent, ce bug n'apparaît qu'avec des conditions limites comme (string-contain "" "").

    Comme les spécifications ne sont pas très précises quant aux cas limites, il y a plusieurs manières de le corriger... qui sont laissées en exercice au lecteur...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. une fonction qui fait le changement de repère
    Par diofilip dans le forum C
    Réponses: 3
    Dernier message: 27/02/2012, 16h15
  2. Réponses: 3
    Dernier message: 14/06/2010, 16h10
  3. Une fonction qui marche 8 fois mais pas 9
    Par Swarley dans le forum Prolog
    Réponses: 1
    Dernier message: 04/12/2008, 11h21
  4. [AJAX] [XMLHttp][IE]Fonction qui ne fonctionne qu'une seule fois
    Par narnou dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 13/07/2007, 12h16
  5. fonction qui s'exécute qu'une seule fois sous Firefox
    Par la.sophe dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 01/03/2006, 11h02

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