Partage
  • Partager sur Facebook
  • Partager sur Twitter

Supprimer des doublons

Sujet résolu
    26 novembre 2019 à 21:37:41

    Bonjour les PythonVores !

    Je reviens vers vous car je n'arrive pas à valider un cas avec mon bout de code.

    Explication : c'est un exercice IOI de composition musicale, où le but est de réussrie à retirer tous doublons de la composition.

    Pour l'instant voici mon code :

    morceau = list(input())
    n = 0
    loop = -1
    while not ((n > 0 and loop == 0) or len(morceau) <= 1 or (loop == 0 and morceau[n] != morceau[n+1])):
            
        if n+2 > len(morceau):
            n = 0
            
        while len(morceau) > 1 and morceau[n] != morceau[n+1] and n+2 < len(morceau):
            loop = 0
            n += 1
                
        while len(morceau) > 1 and n < len(morceau)-1 and (morceau[n] == morceau[n-1] or morceau[n] == morceau[n+1]):
            loop = 1
            if n+1 < len(morceau) and morceau[n] == morceau[n+1]:
                del morceau[n]
                del morceau[n]
            if n > 0 and len(morceau) > 0 and morceau[n] == morceau[n-1]:
                del morceau[n-1]
                del morceau[n-1]    
        
    print("".join(morceau))

    Mon cas bloque sur cette exemple : abcdeffedcba

    Là je bug arrivé en fin de première boucle, car je ne sais pas comment relancer ma vérification.

    Ah pour infos j'essaye de me limiter au notions déjà vu dans France IOI afin de me forcé à utiliser les outils de langage en ma possession :p

    • Partager sur Facebook
    • Partager sur Twitter
      26 novembre 2019 à 22:06:12

      Bonjour,

      Pour information, retirer les doublons se fait avec l'objet set.

      example = "abcdeffedcba"
      
      print(set(example))  # {'c', 'b', 'f', 'a', 'd', 'e'}
      print(''.join(set(example)))  # eabdcf

      mais ce n'est pas ordonné...

      L'autre solution consiste à créer une liste intermédiaire et de vérifier dans ta chaîne si chaque caractère est déjà présent ou non dans cette liste. Si le caractère n'est pas présent on l'ajoute dans la liste, si non, on ne fait rien.

      example = "abcdeffedcba"
      
      my_list = []
      
      for char in example:
          if char not in my_list:
              my_list.append(char)
      
      print(my_list)  # ['a', 'b', 'c', 'd', 'e', 'f']
      print(''.join(my_list))  # abcdef
      

      Après d'autres possibilité, la construction à partir d'une chaîne vide

      example = "abcdeffedcba"
      
      my_string = ''
      for char in example:
          if char not in my_string:
              my_string += char
      
      print(my_string)  # abcdef
      

      Ton algo est bien trop complexe, il faut aller au plus simple et commencer par du code naïf qui fait le travail... et si par la suite on demande plus, dans ce cas analyser plus en détails.

      Je pense que tu souhaitais supprimer les doublons en supprimant la lettre de trop, du coup je verrai un truc comme ci-dessous, mais c'est pas très intuitif,

      example = "abcdeffedcba"
      
      morceau = list(example)
      length = len(morceau)
      n = -1
      while n != -length:
          if morceau.count(morceau[n]) > 1:
              morceau[n] = '0'
          n -= 1
      print(''.join(morceau).replace('0', ''))  # abcdef
      


      Après on peut faire des trucs sympas comme

      from collections import OrderedDict
      
      example = "abcdeffedcba"
      
      print("".join(OrderedDict.fromkeys(example)))  # abcdef
      

      ou

      example = "abcdeffedcba"
      
      print(''.join(sorted(set(example), key=example.index)))

      ou alors de l'algo pure comme sur le site geeksforgeeks.

      -
      Edité par fred1599 26 novembre 2019 à 22:34:02

      • Partager sur Facebook
      • Partager sur Twitter

      Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
      La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

        26 novembre 2019 à 22:32:20

        fred1599 a écrit:

        L'autre solution consiste à créer une liste intermédiaire et de vérifier dans ta chaîne si chaque caractère est déjà présent ou non dans cette liste. Si le caractère n'est pas présent on l'ajoute dans la liste, si non, on ne fait rien.

        example = "abcdeffedcba"
        
        my_list = []
        
        for char in example:
            if char not in my_list:
                my_list.append(char)
        
        print(my_list)  # ['a', 'b', 'c', 'd', 'e', 'f']
        print(''.join(my_list))  # abcdef
        

        Ce code ne marchera pas, car la procédure décrite dans l'énoncé tient compte de la contiguïté des caractères dans la liste ce que l'opérateur in ignore.

        @Arpa

        Tes conditions sont longues, compliquées et redondantes et l'algorithme n'est pas apparent. Je comprends ton souhait de te limiter aux notions déjà vues sur fioi mais cela peut donner un code parfois compliqué. 

        Tu peux arriver très facilement à résoudre cette question en utilisant une liste et ses méthodes pop et append (il ne s'agit nullement de méthodes avancées, bien au contraire, en particulier pour append). En deux mots, pop supprime le dernier élément d'une liste non vide et append en rajoute un. Exemple :

        >>> L=['B', 'I', 'J', 'O', 'U', 'X']
        >>> L
        ['B', 'I', 'J', 'O', 'U', 'X']
        >>> L.pop()
        'X'
        >>> L
        ['B', 'I', 'J', 'O', 'U']
        >>> L.append("S")
        >>> L
        ['B', 'I', 'J', 'O', 'U', 'S']
        >>> 
        

        Cela étant compris, pour ton exo, tu crées une liste vide L et tu disposes de ta liste de lettres (que tu appelles morceau). Tu boucles sur morceau :

        for c in morceau:
        

        et à chaque étape, si L n'est pas vide, tu regardes si le dernier élément de L est égal à c. Si oui, tu le supprimes de L avec pop sinon tu le rajoutes à L avec append. Ça fait un code très simple et qui tient sur 8 lignes. L'idée de base est de simuler une pile.

        On pourrait facilement faire ça sans pop ni append mais ça donne un code plus compliqué.

        -
        Edité par PascalOrtiz 26 novembre 2019 à 22:33:46

        • Partager sur Facebook
        • Partager sur Twitter
          27 novembre 2019 à 0:36:30

          print(*(''.join(x for x in input() if x not in s and not s.add(x)) for s in [set()]))
          • Partager sur Facebook
          • Partager sur Twitter
            27 novembre 2019 à 8:56:47

            Perso j'ai fait cet exo avec une expression régulière :

            import re
            
            zik = input()
            REG = re.compile(r"(.)\1")
            
            while REG.search(zik):
                for l in REG.findall(zik):
                    zik = zik.replace(l * 2, "")
            
            print(zik)
            



            -
            Edité par thelinekioubeur 27 novembre 2019 à 8:59:08

            • Partager sur Facebook
            • Partager sur Twitter
              27 novembre 2019 à 13:43:32

              thelinekioubeur a écrit:

              Perso j'ai fait cet exo avec une expression régulière :


              Chez moi, ton code ne renvoie rien si en entrée on a:

              aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa



              • Partager sur Facebook
              • Partager sur Twitter
                27 novembre 2019 à 19:49:04

                D'après l'énoncé ce résultat est normal si le nombre de a est pair ... de toute façon mon code passe le test

                http://www.france-ioi.org/algo/task.php?idChapter=656&idTask=2240

                -
                Edité par thelinekioubeur 27 novembre 2019 à 19:52:30

                • Partager sur Facebook
                • Partager sur Twitter
                  27 novembre 2019 à 21:33:07

                  Merci à Tous pour vos réponses, qui enrichissent ma logique et particulièrement @PascalOrtiz,
                  qui grâce à son aide ma permis de comprendre le fonctionnement d'une pile et surtout ma permis de mettre de sortir d'une semaine d'entêtement :colere:.

                  Encore merci à tous !

                  • Partager sur Facebook
                  • Partager sur Twitter

                  Supprimer des doublons

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown