-3
votes

Y a-t-il une solution alternative à des valeurs de matrice d'incrémentation conditionnellement sans utiliser si des déclarations? C ++

Si avoir un tableau, xxx pré>

et je veux que chaque chiffre de la matrice représente la quantité d'une chaîne différente, telle que montants [0] = montant; Code> de 'A' code> est trouvé dans une chaîne donnée, existe-t-il de toute façon pour incrémenter chaque valeur sans utiliser si des déclarations? p>

pseudocode Exemple: p> xxx pré>

à la fin de la boucle, en fonction du mot de chaîne, les montants doivent être les suivants: P>

amounts[0] = 2 ('a')
amounts[1] = 2  ('b')
amounts[2] = 0  ('c')
// etc


3 commentaires

Voulez-vous dire sans si des déclarations en général ou sans ramification en général?


Si je comprends, quelque chose comme ++ quantités [mot [i] - 'a']; ?


Vous vous limitez-vous à des ensembles de caractères spécifiques ou êtes-vous à la recherche d'une solution entièrement générique / portable?


5 Réponses :


5
votes

Compte tenu de votre exemple, en supposant que la chaîne entière est en minuscule et les caractères valides, il y a une solution assez simple (c'est-à-dire à dire, vous gérez la validation)

for (int i = 0; i < word.size(); i++) {
    amounts[word[i]-'a']++; // you can also do a pre-increment if you want
}


5 commentaires

Ne pas que ce n'est pas portable. L'un des ensembles de caractères C ++ nécessite une prise en charge ( EBCDIC ) ne maque pas a - z à une plage contiguë.


Juste pour ajouter, puisque personne ne l'a déjà mentionné, ce n'est pas portable.


Convenir sur la question de l'EBCDIC - bien que probablement pas de grande pertinence. Plus critique: Et si nous avons des lettres majuscules et minuscules ou des caractères non alphabétiques dans la chaîne?


@Aconcagua Si vous lisez la première partie de la réponse "En supposant que la chaîne entière est minuscule et des caractères valides, il existe une solution assez simple (c'est-à-dire à dire, vous gérez la validation)"


Mais si vous vouliez une réponse plus générale (et je discuterais mieux), une solution consisterait à faire de la cartographie tous les caractères souhaités aux index appropriés et si le personnage n'est pas dans la cartographie, c'est un caractère invalide et peut être traité cependant que vous voulez



1
votes

Ce que vous voulez:

Output
a: 2
b: 2
c: 0
d: 0
e: 0
f: 0
g: 0
h: 2
i: 0
j: 0
k: 0
l: 2
m: 0
n: 0
...


3 commentaires

"sans utiliser si des déclarations"


Ceci est seulement pour la vérification de la plage. Vous pouvez sûrement sauter si vous ne l'aimez pas.


Je ne vois pas vraiment pourquoi cela est digne d'un bowvote, dont certains sont un peu verbeux mais ...?



1
votes

Utilisez STD :: Unordered_map . Notez que STD :: Unordered_map serait plus efficace si seul un seul caractère est requis. STD :: String permet de compter des chaînes complexes (par exemple, la carte ["Subring"] ++)

Les cartes sont accessibles à l'aide de la notation de support (par exemple, carte [Index]), et peut donc supprimer efficacement le besoin de la nécessité de supprimer si des déclarations. xxx


4 commentaires

On dirait que std :: Unordered_map serait suffisant. Et il n'est pas nécessaire d'initialiser la carte. opérateur [] insérera un élément zéro si la clé n'est pas encore utilisée.


Pourquoi pas std :: Unordered_map ? Payer pour un std :: string Lorsque vous n'avez besoin que d'un seul caractère est un peu excessif.


En outre, cela peut être plus générique si vous autorisez l'utilisateur à spécifier l'alphabet sous forme d'un std :: string , puis remplissez la carte à l'aide d'une boucle, c'est-à-dire std :: string alpha = "ABCDEF ... ", puis écrivez une boucle pour remplir la carte à partir de {A, 0} .


OP a dit qu'il voulait "représenter le montant d'une chaîne différente", l'utilisation de STD :: String. J'aurais peut-être pris trop littéralement. Oui, le caractère serait plus efficace, mais c'est plus flexible. J'ai seulement initialisé pour faciliter la visualisation de la manière dont les valeurs sont conservées.



1
votes

Ce qui suit a de nombreuses chances d'être l'un des plus rapides des questions de comptage: xxx pré>

obtenir des valeurs individuelles est assez efficace: p>

 for(char const* c = "abcdefghijklmnopqrstuvwxyz"; *c; ++c)
     // case-insensitive:
     std::cout << *c << ": " << counts[*c] + counts[toupper(*c)] << std::endl;


2 commentaires

@Aconcagua - la valeur minimale de char_bit autorisé est 8 . (Les normes C ++ font référence aux normes C pour la spécification des macros dans et , et les normes C définissent une limite inférieure de 8 ).


Droite; J'ai mal compris votre réponse. Supprimé mon commentaire.



1
votes

Une solution générale et portable serait xxx

si vous pouvez supposer que l'ensemble de lettres minuscules est une plage contiguë, cela peut être simplifié à xxx

Non (manifesté) si dans ce qui précède. Bien sûr, rien n'empêche std :: comptez () en cours d'exécution en utilisant un.


0 commentaires