2017-10-15 4 views
0

Je m'exerce à poser des questions à partir de Cracking l'interview de codage pour devenir meilleur et juste au cas où, soyez prêt. Le premier problème indique: Rechercher si une chaîne a tous les caractères uniques ou non? J'ai écrit cela et il fonctionne parfaitement:Vérifiez si une chaîne est tous les caractères uniques, à l'exception des espaces

def isunique(string): 
    x = [] 
    for i in string: 
     if i in x: 
      return False 
     else: 
      x.append(i) 
    return True 

Maintenant, ma question est, si j'ai tous les caractères uniques comme dans: Je suis J ' qui serait assez rare, mais laisse le dire se produit par hasard, comment puis-je créer une exception pour les espaces? Je ne considère pas l'espace comme un personnage, donc la fonction retourne True et non False?

+1

utilisation 'isspace()' – mentalita

+2

je suggère simplement courir 'String.replace (» », "")' avant de passer dans votre travail déjà 'fonction isunique' ... – Shadow

+0

@mentalita comment exactement intégreriez-vous isspace()? beacuse si je le fais dans la boucle for, il rend la chaîne un bool et pas itérable – MAUCA

Répondre

1

Maintenant, peu importe la façon dont l'espace ou le nombre de caractères spéciaux dans votre chaîne, il suffit de compter les mots:

import re 
def isunique(string): 
    pattern=r'\w' 
    search=re.findall(pattern,string) 
    string=search 
    x = [] 
    for i in string: 
     if i in x: 
      return False 
     else: 
      x.append(i) 
    return True 



print(isunique('I am J')) 

sortie:

True 

sans mots de l'espace test case:

print(isunique('war')) 
True 

avec des mots l'espace cas de test:

print(isunique('w a r')) 
True 

lettres répéter:

print(isunique('warrior')) 
False 
0

Option 1
L'approche élégante, avec collections.Counter

from collections import Counter 

def isunique(string): 
    return Counter(string.replace(' ', '')).most_common(1)[0][-1] == 1 

Option 2 Un peu plus efficace, mais moins jolie.

def isunique(string): 
    c = Counter() 
    for s in string.replace(' ', ''): 
     c[s] += 1 
     if c[s] > 1: 
      return False 
    return True 
In [141]: isunique('I am JJ') 
Out[141]: False 

In [142]: isunique('I am J') 
Out[142]: True

Cette solution ne sera pas itérer sur la liste entière s'il était possible de détecter un double plus tôt.


Si vos chaînes contiennent plus que des espaces blancs (onglets et des sauts de ligne, par exemple), je vous recommande la substitution à base regex:

import re 
string = re.sub(r'\s+', '', string, flags=re.M) 
0

Créer une liste de caractères que vous voulez considérer comme non caractères et les remplacer dans la chaîne. Ensuite, exécutez votre code de fonction.

Comme alternative, de vérifier l'unicité des personnages, la meilleure approche sera de comparer la longueur de la chaîne finale avec la valeur set de cette chaîne comme:

def isunique(my_string): 
    nonchars = [' ', '.', ','] 
    for nonchar in nonchars: 
     my_string = my_string.replace(nonchar, '') 
    return len(set(my_string)) == len(my_string) 

Sample Run:

>>> isunique('I am J') 
True 

Comme par set() document du Python:

Renvoie un nouvel objet set, éventuellement avec des éléments issus de iterable. l'ensemble est une classe intégrée. Voir set et Set Types - set, frozenset pour la documentation sur cette classe.

-1

solution simple

def isunique(string): 
    return all(string.count(i)==1 for i in string if i!=' ') 
+1

Simple! = Meilleur. Cette fonction a une complexité quadratique et est vraiment lente. –

0

Et ... un pool de réponses est jamais complète moins qu'il y ait aussi une solution de regex:

def is_unique(string): 
    import re 
    patt = re.compile(r"^.*?(.).*?(\1).*$") 
    return not re.search(patt, string) 

(Je laisserai la gestion des espaces en tant que exercice à l'OP)