Plusieurs valeurs depuis valeur unique [algo]

Résolu/Fermé
niahoo Messages postés 247 Date d'inscription lundi 24 décembre 2007 Statut Membre Dernière intervention 23 mai 2010 - 4 janv. 2010 à 19:34
niahoo Messages postés 247 Date d'inscription lundi 24 décembre 2007 Statut Membre Dernière intervention 23 mai 2010 - 5 janv. 2010 à 02:35
ok les gens,

déja bonjour et bienvenue dans ma galère.

je ne sais pas trop comment expliquer ma question. j'espere que beaucoup d'entre vous qui me liront auront bidouillé sur excel et vba pour me comprendre.
ATTENTION, c'est bien en php que je souhaite réaliser cet algo.

Rappelez vous, en VBA excel, on peut afficher à l'utilisateur une boîte de dialogue (dans le genre msgbox mais avec des boutons : Ok, Annuler, Kikoo, Browse, etc...)

c'est là que ta galère commence, cher lecteur, car ce que je vais expliquer ensuite, les valeurs dont je parle, ne peuvent être transmises à partir d'une boite de dialogue à boutons puique quand on cliquait sur un bouton sur excel, la boite se fermait et donc seule la valeur du bouton était transmise, pas de doute possible quant à la réponse de l'utilisateur.

ce qui suit n'a donc que très peut de rapport avec ce qui précède.

mouah

une liste des réponses possibles est répertoriée dans une liste de valeurs uniques qui sont, il me semble, des puissances de 2, en plus de la valeur 1, et peut être la valeur 0.

par exemple:

1 : osef
2: chien
4: chat
8: poisson

si la valeur retournée par l'utilisateur est 12, on devine donc qu'il à sélectionné chat + poisson.

si c'est 10, il a sélectionné chien + poisson


voilà je ne sais pas trop si tu me suis, ami lecteur, mais j'aimerais reconstituer cet algorithme qui me permettrait de retrouver les différentes options choisies à partir d'une valeur unique. Comment retrouver que l'utilisateur à bien choisi chien et poisson à partir d'un simple "10" ? Comment décomposer la somme de puissances de 2 pour en retrouver les opérandes ?

Bien sur, l'intéret est de ne pas se taper une centaine de if/else.. car des choix différents je compte en proposer pas mal !

Est-ce que c'est possible ? ou est-ce qu'en VBA l'interpréteur à une fonction de 150 lignes remplies de if/else selon vous ?

voilà je ne suis pas une bête en maths sinon j'aurais pu trouver je pense, mais je n'ai pas peur de me coltiner de la doc et les les algo géants ne me font pas peur non plus.

merci si vous avez compris.

et merci si vous pouvez m'aider,

allez, à ¨+

edit : je me base sur une technique qui date de l'égypte antique qui semble marcher "selon wikipedia" mais bon je ne sais pas vraiment organiser mes tests à grande échelle pour valider ça. En somme ce que je veux c'est un algo, même s'il n'est pas formaté en php mais en simple français !
A voir également:

6 réponses

Pacorabanix Messages postés 3248 Date d'inscription jeudi 23 août 2007 Statut Membre Dernière intervention 19 mai 2013 661
4 janv. 2010 à 22:12
c'est une technique très utilisée de nos jours encore en informatique.

En fait, le plus simple est d'écrire les nombres en binaire pour le comprendre, j'espère que ça ne te fait pas peur, tu verras ça en vaut la peine :

écriture décimale = écritures binaires
1 = 1      (0001)
2 = 10     (0010)
4 = 100    (0100)
8 = 1000   (1000)


J'ai rajouté comme tu peux le voir des "zéros" devant les chiffres. Ils sont inutiles, mais l'ordinateur stocke des nombres ainsi (sur 8 ou 16 cases habituellement pour les petits nombres entiers)


Ainsi, si on choisit chien (deuxième choix, 0010) et chat (troisième choix 0100), et qu'on additionne ces nombres, on trouve 0110 . En gros, lorsqu'il y a un "1" dans la case correspondant au choix, c'est qu'il est pris. S'il y a "0", c'est qu'il n'est pas pris. On comptes les cases depuis la fin (le chiffre qui a le moins de valeur c'est celui de droite).

L'algorithme c'est :
pour chaque choix possible : regarder le nombre tout à droite (le reste modulo 2 du nombre de base).
  si c'est un 1, alors l'option est "cochée",
  sinon l'option n'est pas cochée.
Recommencer après avoir supprimé le dernier chiffre (décalage de bits vers la droite ou division entière par 2) jusqu'à avoir parcouru toutes les options.


Manipuler ceci ne pose aucun problème à un ordinateur, bien au contraire on fait cela car justement les processeurs ont souvent des "routines" optimisées pour traiter ce genre de cas. De plus on économise de la mémoire (dans une variable de 16 bits on peut stocker les réponses "coché" ou "pas coché" à 16 questions, un bit = une information.


De plus, si on veut tester si une option en particulier est prise (ex : a t-i choisit le poisson ?), il suffit de voir si le nombre 1 est en 4ème position ou pas.
En pratique, on utilise le XOR ("ou" exclusif binaire)
nombre XOR 1000 -> si le résultat est nul, l'option n'est pas cochée, sinon elle l'est.
Ex : 0110 XOR 1000 = 0000 -> le poisson n'est pas dans la liste.
1110 XOR 1000 = 1000 -> le poisson est dans la liste.




j'espère que c'était (un peu) clair, si tu as d'autres questions n'hésite pas.

Petite question "exercice" pour comprendre : alors, un des choix était-il "0" ou pas ?
2
niahoo Messages postés 247 Date d'inscription lundi 24 décembre 2007 Statut Membre Dernière intervention 23 mai 2010 19
5 janv. 2010 à 01:27
excellent, c'est même beaucoup plus clair comme ceci finalement ! ça permet carrément d'avoir un simple bit pour chaque valeur.

merci beaucoup!

bon par contre, si je connais théoriquement le décalage de bits en C++ pour avoir lu mon bouquin là dessus, je ne sais pas du tout si ça va être possible en php.

il va me falloir en plus savoir transformer un entier en version binaire puis prendre ce binaire pour en faire une string et tester les valeurs de caractères, ou trouver le XOR en php. je m'y colle ce soir ^^ (en commençant par le XOR d'ailleurs ça doit bien exister même si php est assez chiant là dessus avec son typage faible. quand on à goûté à la simple surdéfinition de fonctions avec des prototypes à même nombre d'arguments mais différents types on se casse les dents en php pour arriver à faire des classes aussi simple d'utilisation qui n'utilisent que quelques noms de fonctions, obligé de faire varier le nombre d'arguments sur des fonctions sans arguments définis ce qui fait que l'IDE ne les indique pas lors de la saisie..

tiens je continue cette petite digression, après tout c'est mon topic :P, je me rappelle avoir utilisé une technique similaire pour un petit moteur de recherche. le HTML envoyait dans les headers (POST) une chaine de type 0111010101 qui correspondaient ici aussi à des options cochées. (seulement certains choix avaient plusieurs choix ce qui pouvait donner des 1002301320 et là ça marchait). Quand on n'envoyait que des 0 et des 1 dans cette chaine, je précise chaîne, c'est important, j'avais parfois une erreur incompréhensible.

incompréhensible jusqu'à ce que l'on comprenne évidemment, j'avais beau traiter ça comme une chaîne, php se transmettait ça comme il voulait.. j'ai fait un echo de ce que je recevait dans mon moteur et mon beau "101101110" s'était transformé en 543.. un vieil integer de la mort..

aaah j'adore raconter ma vie moi. bon du coup ça me fait penser que traiter du binaire doit pas être bien compliqué mais qu'il faudra que je sois prudent. il est temps de fermer cette parenthèse)

Pour l'exercice, je dirais donc que le 0 n'était pas un choix, puisqu'il correspondrait si j'ai bien suivi à aucune case cochée...
mais sur une boite de dialogue on pourrait quand même s'en servir je suppose, ce qui correspondrait visuellement, pour l'exemple, à avoir cliqué sur la croix de la fenêtre. çe serait redondant avec annuler qui aurait été doté de la valeur 1.

Mais tant qu'on y est, il me semble avoir lu qu'en C++, les nombre négatifs étaient signés et donc que leur premier bit valait 1. Et que par conséquent le zéro pouvait aussi s'écrire 11111111. Si je ne me trompe pas, et que ma fonction check 8 options, et que les 8 sont cochées, j'ai pas intéret à faire des tests sur la valeur binaire de 0 moi.. j'espère me tromper du coup.

merci :)

edit : bon ben tout est prévu, au boulot : http://209.85.229.132/search?q=cache:4kTi-abv0xIJ:www.commentcamarche.net/contents/php/phpop.php3+php+xor+binaire&cd=1&hl=fr&ct=clnk&gl=fr&client=opera
0
niahoo Messages postés 247 Date d'inscription lundi 24 décembre 2007 Statut Membre Dernière intervention 23 mai 2010 19
5 janv. 2010 à 01:43
détail technique:

si j'en crois ce que j'ai lu dans la page que j'ai linké au dessus, il y a une complexité qui m'échappe dans ton exemple

nombre XOR 1000 -> si le résultat est nul, l'option n'est pas cochée, sinon elle l'est. 
Ex : 0110 XOR 1000 = 0000 -> le poisson n'est pas dans la liste. 
1110 XOR 1000 = 1000 -> le poisson est dans la liste.


^
	OU exclusif
	Retourne 1 si l'un des deux bits de même poids est à 1 (mais pas les deux)
	9 ^ 12 (1001 ^ 1100)    ===>	5 (0101)


selon cette doc, 0110 XOR 1000 donnerait 1110

il n'aurait pas pris l'option 4eme mais pourtant le résultat n'est pas nul. çe ne marcherait que s'il prend une seule option.
bon je peux tester, si le résultat est supérieur à 0111 il l'a pris, sinon non.
0
Pacorabanix Messages postés 3248 Date d'inscription jeudi 23 août 2007 Statut Membre Dernière intervention 19 mai 2013 661
5 janv. 2010 à 01:57
j'ai dit n'importe quoi, excuse-moi... je voulais dire AND (et) !
0
Pacorabanix Messages postés 3248 Date d'inscription jeudi 23 août 2007 Statut Membre Dernière intervention 19 mai 2013 661
5 janv. 2010 à 01:59
le XOR est utilisé pour "switcher" une option particulière :

0110 : il n'a pas de poisson
0110 XOR 1000 = 1110 : il a un poisson maintenant
1110 XOR 1000 = 0110 : il n'en a plus
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
niahoo Messages postés 247 Date d'inscription lundi 24 décembre 2007 Statut Membre Dernière intervention 23 mai 2010 19
5 janv. 2010 à 02:06
arf pendant ce temps j'ai bidouillé et je suis arrivé à ce qui suit.

tu es tout excusé :) tu m'as mis sur la voie c'est le principal, le reste ce sont des tests et de la transcription dans un langage mais je sais maintenant qu'en passant en binaire j'ai toutes mes options prêtes à lire, mon problème est donc résolu !


Effectivement avec le AND c'est plus clair :) et c'est nickel merci beaucoup
(j'étais en train de réfléchir à l'inverse : utiliser le OU normal en inversant le testeur, mais bon ça revient exactement au même sauf que y a ptetre une siouxerie à faire en combinant les deux)

Ex : 0110 OR 0111 = 0111 -> c'est différent de 1111 donc le poisson est n'y est pas
1110 OR 0111 = 1111 -> = 1111 donc le poisson est choisi..

je teste l'option 2: (ptain je floode moi)

Ex : 0110 OR 1101 = 1111 -> ok pour opt2
1100 OR 1101 = 1101  != 1111  pas d'opt2


fin bon merci pour ta patience, ça "raukse"

edit : ah pratique le switch aussi.. on en apprend tous les jours c'est cool
0
Pacorabanix Messages postés 3248 Date d'inscription jeudi 23 août 2007 Statut Membre Dernière intervention 19 mai 2013 661
5 janv. 2010 à 02:12
oui ça marche aussi comme ça (car en effet OU + négation = AND en logique).
Mais c'est mieux comme j'ai fait moi :-p pour la simple raison que dans ce cas tu obtiens "0" ou "non 0", ce qui équivaut à "false" ou "true", ce qui est bien pratique pour programmer de façon élégante.

Ensuite, je tiens à te rappeler, si tu implémentes ça, que l'histoire de l'écriture binaire permet de juste de visualiser et de comprendre le truc, en pratique tu utilises des nombres décimaux (1, 2, 4, 8 dans nos exemples ) ou hexadécimaux dans ton code, bien sûr. (si possible des "unsigned", pour éviter des surprises avec les négatifs et leur manière d'être codés)

Petite remarque : c'est comme ça que fonctionnent souvent diverses options à activer selon un paramètre lorsqu'on fait appel à des API (ex : la fonction de l'API Windows qui fait apparaitre une boite de message).
0
niahoo Messages postés 247 Date d'inscription lundi 24 décembre 2007 Statut Membre Dernière intervention 23 mai 2010 19
5 janv. 2010 à 02:35
oui oui je AND est plus "élégant" et pratique je suis bien d'accord.

donc en pratique je code simplement avec des valeurs en int, et c'est le fait d'utiliser '&' au lieu de '&&' ou 'AND' qui va faire la comparaison bit a bit si je comprends bien. encore plus simple alors. (j'ai pas fait de tests ce soir encore mais j'upperai le topic quand mon appli en sera arrivée à la. ceci dit c'est pas demain la veille j'ai pas fait d'interface de toute façon encore, je me fais un beau core et ensuite mes interfaces HTML sont produites par lui composant par composant donc ça vient à la fin)

Mais comme je le disais, le php est chiant avec son typage (trèèèèès) faible. pas moyen de demander un unsigned. pas moyen de demander un int de toute façon. c'est ce donc je parlais avec mon 543, je lui avais passé une string composée de 0 et de 1 il m'a transformé ça en int correspondant à cet octet.

mais bon, dans l'autre sens, comme les navigateurs envoient des strings, ça devrait pas être complexe pour qu'il me les prenne comme des int. l'un dans l'autre, quelques tests de sécurité et ça sera plié.
0