CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[C++]Switch et chaine de caractère

dnob700
dnob700
Niveau 10
29 juin 2004 à 23:02:33

Salut,

je suis en train de créer un programme en ligne de commande, et justement, il y a quelques commande à rentrer.
Je voulais alors tester quelle commande avait été rentré avec un switch, mais, je me suis apercue qu´on ne peut pas utiliser switch avec des chaine de caractères. Ce n´est d´ailleurs pas étonnant.

J´ai eue une idée : c´est de calculer un hash pour toutes les commande que l´utilisateur pourrait rentrer, puis de calculer le hash de la commande qu´il a effictivement rentrée et de faire le switch sur cette valeur.

La méthode est-elle bonne, ou bien existe-t-il une méthode plus simple et meilleur que ej ne connaitrais pas ?

merci d´avance pour vos réponse.

Evanescence
Evanescence
Niveau 5
30 juin 2004 à 00:15:19

une hashtable, c´est pas l´idéal.
des if imbriqués c´est bien. Mais si ça t´emmerde, tu peux faire un truc du genre :

struct s_commande{
char nom[N];
int index;
};
s_commande commandes[M]={{"truc",0},{"machin"},1},...};

Puis une tiote fonction du genre
int getIndexFromName(char name[]){
for(int i=0;i<M;i++)
if(!strcmp(name,commandes[i].nom))return commandes[i].index;
}

A partir de là, tu peux faire ton switch.

Evanescence
Evanescence
Niveau 5
30 juin 2004 à 00:18:47

En fait, tu peux même aller plus loin, en remplaçant index par void ( *f)(void *);
A partir de là, au lieu de te taper un switch, tu fais :
for(int i=0;i<M;i++)

if(!strcmp(name,commandes[i].nom))commandes[i].f()
;

dnob700
dnob700
Niveau 10
30 juin 2004 à 00:20:31

Parce que ce que j´ai utilisé, c´est de définir, a l´écriture du code, des constante qui ont l´air tout a fait arbitraire :

  1. define CMD_QUIT 1953068401
  2. define CMD_HELP 1886152040

mais qui sont en fait el résultat donné pour ces commandes par ma fonction de hachage.

et je fait pour récupérer ce qui a été entré par l´utilisateur :
cin > > CMD;
cmd=Hash(CMD);
switch ( cmd)
case CMD_HELP
. ..

plus j´ai une comande caché pour calculé les nouveau hash d´autre fonction, je trouve ça assez joli comme méthode, quelle en est le défaut ? si tu me conseile plutot les id imbriqué qui sont censé être moins bon.

dnob700
dnob700
Niveau 10
30 juin 2004 à 00:21:54

a, j´avais pas vu ton deuxième post, c´est vrai que là ca commence à devenir intéressant.

Evanescence
Evanescence
Niveau 5
30 juin 2004 à 16:10:36

Le défaut des hash, ce sont les collisions. Mais à priori, tu devrais pas en avoir ( à priori)

Kouic
Kouic
Niveau 9
30 juin 2004 à 17:10:32

A la place d´un hash, pourquoi pas une liste de structure toute simple?
struct tMachin { std::string strNom; int iVal; }

std::vector m_lstCmd;
pour toutes les commandes:
m_lstCmd.push_back(tMachin remplie)

Puis pour le reste
string = argv[x];
Pour tout les cmd dans m_lstCmd:
si cmd.strNom == string alors:
id = cmd.iVal;

switch(id)

Mais, pour faire mieux encore, remplace le tMachin par une classe avec une methode virtuelle ( du genre Execute() ) , creer autant de derivés que de commandes...
Ce qui donnerait:
string = argv[x];
Pour tout les cmd dans m_lstCmd:
si cmd.strNom == string alors:
cmd.Excecute()

Ensuite avec libjit, tu charges le code liés au methodes Execute() surchargées et tu l´execute a la volée...

Quoi ? Je m´embale trop vite ? NOnnnn...
Ca doit etre la chaleur :)

Altonfrere
Altonfrere
Niveau 10
30 juin 2004 à 17:49:39

rien à voir avec le topic mais c´était juste pour réagir à :

" Le défaut des hash, ce sont les collisions. Mais à priori, tu devrais pas en avoir ( à priori)"

Il existe des fonctions de hash sans collisions ( appellées " minimal perfect hash function"). Le principe est qu´en ayant un ensemble fini ( important le " fini") de chaînes de caractères, cette méthode va calculer la fonction idéale pour répartir les index sur l´ensemble des chaines examinées.

Et la cerise sur le gâteau : l´ordre est conservé ( l´ordre dans lequel le tableau est trié).

Enfin voilà c´était juste pour information...

Altonfrere
Altonfrere
Niveau 10
30 juin 2004 à 18:50:38

oops petite bourde . .. non pas l´ordre qui est convervé mais l´intervalle de définition des clés. Pour un tableau de 0 à N les hashkeys seront comprises dans cette intervalle là.

Evanescence
Evanescence
Niveau 5
30 juin 2004 à 19:41:10

C´est pour ça que je disais " à priori". On peut avoir une fonction de hashage parfaite dans son cas, dans la mesure où il y a peu de données.

Par contre, si tu me trouves une fonction de hashage parfaite pour 2^64 possibilités ( puis 2^128) ça m´intéresse :P

Altonfrere
Altonfrere
Niveau 10
30 juin 2004 à 19:55:09

" On peut avoir une fonction de hashage parfaite dans son cas, dans la mesure où il y a peu de données"

Justement non, si l´ensemble est trop petit c´est pas dit qu´il existe une telle fonction. Ca marche bien à partit d´un certain nombre minimum d´entrées ( assez faible de toute facon).

" Par contre, si tu me trouves une fonction de hashage parfaite pour 2^64 possibilités ( puis 2^128) ça m´intéresse "

Trouve moi déjà un exemple UTILE qui exploite un tel ensemble on en reparle après :) il est assez rare d´avoir à traiter autant de chaines ( différentes qui plus est)

Sinon ya toujours moyen de faire du hash à plusieurs niveaux, en subdivisant l´ensemble, ou encore pour le 64 tu peux toujours coder tes clés sur 64 bits.

Evanescence
Evanescence
Niveau 5
30 juin 2004 à 21:55:06

" Trouve moi déjà un exemple UTILE qui exploite un tel ensemble on en reparle après il est assez rare d´avoir à traiter autant de chaines ( différentes qui plus est)"
Il n´est plus question de chaines, mais un tel truc peut être intéressant pour faire de la détection de positions déjà rencontrées ( zobrist keys), ou encore détection de déplacement neutres pour certaines pièces données ( cad, tu déplaces une piece A, de telle façon que les déplacements possibles d´une piece B ne changent pas). Pour un jeu d´échecs.
Je disais pas ça en l´air tu vois ; )

" " On peut avoir une fonction de hashage parfaite dans son cas, dans la mesure où il y a peu de données"

Justement non, si l´ensemble est trop petit c´est pas dit qu´il existe une telle fonction. Ca marche bien à partit d´un certain nombre minimum d´entrées ( assez faible de toute facon)."
Admettons qu´on ait 3 chaines : " commande 1", " commande 2", " quitter".
" commande 1"->1
" commande 2"->2
" commande 3"->3
C´est plus vraiment des nombres sortis d´une fonction de hashage, mais c´est bien suffisant.
Comme quoi... :P

JeanYvesYves
JeanYvesYves
Niveau 10
01 juillet 2004 à 08:06:59

Moi je voudrais juste réagir la dessus :

s_commande commandes[M]={{"truc",0},{"machin"},1},...};

je pense que la 2e donnée, que tu appelles " index" est inutile, car si j´ai bien compris :

commandes[X].index = X tout le temps...

Evanescence
Evanescence
Niveau 5
01 juillet 2004 à 14:04:52

Bah, dans le cas de dnob, index!=X ; )
Mais sinon, oui. c´est inutile.

dnob700
dnob700
Niveau 10
01 juillet 2004 à 18:06:21

Pour ma fonction de hash, j´utilise un unsigned long, et pour le premier caractère de la chaine, je fait un xor avec le premier octet du long, pour le deuxième caractère avec le deuxième octet, et arrivé au quatrième, je repart au premier...

Bien sur, il est très probable qu´un mot que je n´ai pas testé est le même hash qu´une de mes commande, par contre, il est très peu probable que l´utilisateur rentre ce mots. A l´opposé, pour l´instant je n´ai pas eu de collision, mais sinon, je peut toujours modifier le nom de la commande pour résoudre.

merci quand même pour toutes vos réponse, juste Kouic, je n´ai pas compris ton truc, vu que je ne sais pas ce qu´est un vector, mais c´est pas grave, je regarderais une autre fois.

Kouic
Kouic
Niveau 9
01 juillet 2004 à 19:29:38

Nan, t´enfais pas dnob700, l´idee que j´ai proposée est realisable mais c´est tres . .. comment dire . ... tres C++. Ou plus simplement comment faire 3252 lignes de code C++ la ou 124 lignes de C suffiraient :)

Sinon, les vectors sont des listes chainées, simples et efficaces.

Sous forums
  • Aide à l'achat Mac
  • Création de Jeux
  • Linux
  • Création de sites web
  • Programmation
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment