6
votes

Enlevez les lettres courantes dans les chaînes

J'ai donc un problème intéressant.

J'essaie d'écrire un mot de jeu, et j'ai besoin de savoir quelles lettres que j'ai utilisées et que je n'ai pas faites. Jusqu'à présent, j'ai le code ci-dessous: xxx

Ce que je cherche un moyen simple d'éliminer les lettres dans les deux, mais laissez des doublons si nécessaire.

  1. Les chaînes sont converties en minuscules, les non-lettres sont supprimées
  2. Duplicate matière, donc si x = "aa" et y = "a" , alors le résultat est "A" , pas "" . Cela empêche l'utilisation des ensembles, je pense.
  3. Si une lettre est dans Y, ce n'est pas dans X, cela devrait dire cela fort.
  4. La vitesse n'est pas importante, mais l'élégance du code est. Donc, le plus gentil, le code est de lire le meilleur type de subjectif que je connais.
  5. La commande de sortie n'est pas importante, car je peux simplement convertir en chaîne et trié () IT.

    J'ai examiné d'autres réponses, mais celles-ci sont principalement liées à seulement donner les lettres qui n'apparaissent pas dans un seul et déposent des doublons.


10 commentaires

Pourriez-vous s'il vous plaît ajouter des exemples d'entrée / sortie supplémentaires?


@Haidro 2 Plus ajouté.


@Haidro: Je ne comprends pas votre premier exemple: pourquoi n'est-ce pas bcdeloostu ? Qu'est-il arrivé au o S, le l et le troisième t ? Dans la deuxième exférence, pourquoi le i soustrait-il?


Vous dites des duplicats importantes, mais votre premier exemple a des occurrences en double de «A». Voulez-vous dire adjacents duplicats?


@ 2RS2TS: cette partie a du sens pour moi, car il y a deux A s dans les premier et 2 A S dans la seconde


Si une lettre est dans Y, ce n'est pas dans X, il devrait dire cela fort. dans votre premier exemple, v est dans Y mais pas x x . Pourquoi ne l'avez-vous pas "disant quoi que ce soit fort"?


@Haidro whoops vous avez raison, le premier exemple est faux, je devais éliminer les lettres à la main. Maintenant, vous pouvez comprendre mon dilemme!


Je ne sais pas pourquoi vous m'adressez: p. C'était @davidrobinson qui l'a pointé, et je pense qu'il me faisait accidentellement piquer


@Haidro: Oh, je suis vraiment désolé. On dirait que tout le monde vous pique accidentellement.


@Davidrobinson hah il va bien


3 Réponses :


7
votes

Vous pouvez utiliser collections.Counter code> des objets, qui peuvent être soustraits les uns des autres: xxx pré>

comme une démonstration de ce qui se passe: p>

>>> c1 = collections.Counter("hello world")
>>> c2 = collections.Counter("hey worlds")
>>> c1 - c2
Counter({'l': 2, 'o': 1})
>> (c1 - c2).elements()
['l', 'l', 'o']


3 commentaires

J'ai peut-être lu trop? Mais cela ressemblait à ce qu'il voulait conserver la commande (+1) pour le comptoir de la même manière


La commande de sortie n'est pas importante, je mettrai à jour les règles pour l'énoncer.


@Joranbeasleas: Non, sinon il n'aurait pas trié chaque chaîne pour commencer avec



1
votes

Collections.Counter code> ne laissera pas de comptage aller sous zéro si vous utilisez l'opérateur - code>. Toutefois, si vous utilisez C.Subrent (D), il vous permettra de le faire. En outre, lors de l'utilisation de C.Elements (), les valeurs avec des comptes négatifs sont ignorées.

Voici une implémentation basée sur des collections.Conter: P>

cz = collections.Counter(cy) # because c.subtract(..) modifies c
cz.subtract(cx)
for letter, count in cz.iteritems():
    if count == cy[letter]: # in the case that there were none of letter in x
        assert False


4 commentaires

Ne gère pas d'échec sur les lettres dans y qui ne sont pas dans x


Ah, bonne prise. J'ai mal interprété cette exigence. Dans ce cas, l'utilisation de la combinaison de CX-CY et CY-CX semble être la voie à suivre.


@ J.davidsmith: votre solution pourrait gérer cela en faisant si (compte) <0: élever ... Je fais comme le mien, mais je pense que cela peut être plus efficace car il n'effectue qu'une seule soustraction . (Cependant, l'utilisation d'une concaténation de chaîne est un peu plus lente que "". Joindre , alors qui sait).


@Davidrobinson: si compte <0: élever ... échoue dans le scénario où String X a n de lettre L, tandis que y a une m de lettre l où n Nombre <0 == true . Comme je l'ai dit dans mon poste, il n'est pas clair, ce qu'il voulait; D'autres ont fourni la solution dans laquelle le nombre de comptes <0 soulève une exception, donc j'ai fourni l'alternative.



1
votes

Bâtiment sur la réponse de David Robinsons:

import collections.Counter as C
def remove_common(x,y):
    s1,s2=filter(str.isalpha, x.lower()),filter(str.isalpha, y.lower())
    c1,c2 = C(s1),C(s2)
    if any(c2-c1):
        assert False
    return list((c1-c2).elements())

>>> remove_common('hi there','hi')
['h', 'r', 'e', 'e', 't']
>>> x,y='Lets chat about code','that cool cat'
>>> remove_common(x,y)
['u', 's', 'b', 'e', 'e', 'd']
>>> remove_common('hi','ho')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in remove_common
AssertionError


0 commentaires