Un compteur avec des lettres, comment faire -simple- ?

Un compteur avec des lettres, comment faire -simple- ? - PHP - Programmation

Marsh Posté le 22-05-2004 à 14:04:44    

Je dois générer des series de code à base de 4 lettres (exemple: AAAA,AAAB,AAAC,...,CKRI,...,FFFF ;) ) en partant d'un de ces codes (je génère les x codes suivants)
J'ai réfléchi à l'algorytme faisant ca, et j'ai quelques idées mais je sens que je risque de reinventer la roue, donc si quelqu'un à une bonne méthode pour faire ca, qu'il n'hesite pas :D  
(pour ma part je posterai ma fonction ici quand je l'aurai finit :wahoo: )

Reply

Marsh Posté le 22-05-2004 à 14:04:44   

Reply

Marsh Posté le 22-05-2004 à 14:52:57    

je le ferais comme ça :
4 tableaux de 26 éléments
tu initialises en fonction de ta série de lettre
tu fais une boucle qui incrémente de 1 sauf si fin de tableau, auquel cas début de tableau puis meme chose sur le suivante et ainsi de suite

Reply

Marsh Posté le 22-05-2004 à 15:48:08    

4 lettres, cela fait 456976 combinaisons
tu peux créer un compteur de 1 à 456976, tu décomposes le compteur en coef_1 * (26*26*26) + coef_2 * (26*26) + coef_3 * 26 + coef_4
Chacun des coefs correspond au numéro d'ordre des lettres dans l'alphabet.
coef_4 = compteur % 26
coef_1 = .... (euh je complète plus tard, car j'ai fait une erreur)


Message édité par T509 le 22-05-2004 à 15:53:20

---------------
fermez vos topics résolus avec le tag [Résolu] en fin de titre. Merci !
Reply

Marsh Posté le 22-05-2004 à 16:09:40    

Bonne idée !
 
Bon finalement j'ai fais ca:

Code :
  1. function lettreSuivante($actuelle)
  2. {
  3. switch($actuelle)
  4. {
  5.  case 'A': $suivante = 'B'; break;
  6.  case 'B': $suivante = 'C'; break;
  7.  case 'C': $suivante = 'D'; break;
  8.  case 'D': $suivante = 'E'; break;
  9.  case 'E': $suivante = 'F'; break;
  10.  case 'F': $suivante = 'G'; break;
  11.  case 'G': $suivante = 'H'; break;
  12.  case 'H': $suivante = 'I'; break;
  13.  case 'I': $suivante = 'J'; break;
  14.  case 'J': $suivante = 'K'; break;
  15.  case 'K': $suivante = 'L'; break;
  16.  case 'L': $suivante = 'M'; break;
  17.  case 'M': $suivante = 'N'; break;
  18.  case 'N': $suivante = 'O'; break;
  19.  case 'O': $suivante = 'P'; break;
  20.  case 'P': $suivante = 'Q'; break;
  21.  case 'Q': $suivante = 'R'; break;
  22.  case 'R': $suivante = 'S'; break;
  23.  case 'S': $suivante = 'T'; break;
  24.  case 'T': $suivante = 'U'; break;
  25.  case 'U': $suivante = 'V'; break;
  26.  case 'V': $suivante = 'W'; break;
  27.  case 'W': $suivante = 'X'; break;
  28.  case 'X': $suivante = 'Y'; break;
  29.  case 'Y': $suivante = 'Z'; break;
  30.  case 'Z': $suivante = 'A'; break;
  31. }
  32. return $suivante;
  33. }
  34. function decoupeChaineEnTableau($chaineADecouper)
  35. {
  36. $j = strlen($chaineADecouper);
  37. for($i = 0 ; $i < $j ; $i++)
  38. {
  39.  $tabchaine[] = substr($chaineADecouper,$i,1);
  40. }
  41. $tabchaine = array_reverse($tabchaine);
  42. return $tabchaine;
  43. }
  44. function serie($chaine,$nb,$pre,$suf)
  45. {
  46. $tableauFinal = array();
  47. $tabchaine = array();
  48. $tabchaine = decoupeChaineEnTableau($chaine);
  49. $tableauFinal[] =         $pre.$tabchaine[3].$tabchaine[2].$tabchaine[1].$tabchaine[0].$suf;
  50. for($u = 0 ; $u < $nb - 1 ; $u++ )
  51. {
  52.  $tabchaine[0] = lettreSuivante($tabchaine[0]);
  53.  if($tabchaine[0] == 'A')
  54.  {
  55.   $tabchaine[1] = lettreSuivante($tabchaine[1]);
  56.   if($tabchaine[1] == 'A')
  57.   {
  58.    $tabchaine[2] = lettreSuivante($tabchaine[2]);
  59.    if($tabchaine[2] == 'A')
  60.    {
  61.     $tabchaine[3] = lettreSuivante($tabchaine[3]);
  62.    }
  63.   }
  64.  }
  65.  $tableauFinal[] = $pre.$tabchaine[3].$tabchaine[2].$tabchaine[1].$tabchaine[0].$suf;
  66. }
  67. return $tableauFinal;
  68. }
  69. $numero = array();
  70. $annee = getdate(mktime());
  71. $numero = serie($premiereChaine,$nbetiquettetotal,'',substr($annee['year'],2,4));


Message édité par aspegic500mg le 22-05-2004 à 16:33:12
Reply

Marsh Posté le 22-05-2004 à 16:42:10    

Moi j'ai ceci finalement :
 

Code :
  1. <?php
  2. function compteur2alpha ($compteur) {
  3. //pour compteur sur 8 lettres majuscules (208827064576 max)
  4. $compteur = is_int($compteur) ? $compteur : floor($compteur);
  5. //on décompose le compteur en multiple des puissances de 26
  6. $coef_1 = floor($compteur / pow(26, 7));
  7. $coef_2 = floor(($compteur - ($coef_1 * pow(26, 7))) / pow(26, 6));
  8. $coef_3 = floor(($compteur - ($coef_1 * pow(26, 7)) - ($coef_2 * pow(26, 6))) / pow(26, 5));
  9. $coef_4 = floor(($compteur - ($coef_1 * pow(26, 7)) - ($coef_2 * pow(26, 6)) - ($coef_3 * pow(26, 5))) / pow(26, 4));
  10. $coef_5 = floor(($compteur - ($coef_1 * pow(26, 7)) - ($coef_2 * pow(26, 6)) - ($coef_3 * pow(26, 5)) - ($coef_4 * pow(26, 4))) / pow(26, 3));
  11. $coef_6 = floor(($compteur - ($coef_1 * pow(26, 7)) - ($coef_2 * pow(26, 6)) - ($coef_3 * pow(26, 5)) - ($coef_4 * pow(26, 4)) - ($coef_5 * pow(26, 3))) / pow(26, 2));
  12. $coef_7 = floor(($compteur - ($coef_1 * pow(26, 7)) - ($coef_2 * pow(26, 6)) - ($coef_3 * pow(26, 5)) - ($coef_4 * pow(26, 4)) - ($coef_5 * pow(26, 3)) - ($coef_6 * pow(26, 2))) / 26);
  13. $coef_8 = ($compteur % 26);
  14. $code = chr(64+$coef_1).chr(64+$coef_2).chr(64+$coef_3).chr(64+$coef_4).chr(64+$coef_5).chr(64+$coef_6).chr(64+$coef_7).chr(64+$coef_8);
  15. return ltrim($code, "@" );
  16. }
  17. function code_suivant($code) {
  18. //code fait de 4 lettres
  19. $code = strtoupper($code)
  20. if (ereg("[A-Z]{1, 8}", $code)) {
  21.  $code = str_pad($code, 8, "@", STR_PAD_LEFT); //pour avoir une chaine de 8 caracteres, @ retournera une valeur 0 dans le calcul
  22.  $compteur  = (ord($code{0}) - 64)*pow(26,7);
  23.  $compteur += (ord($code{1}) - 64)*pow(26,6);
  24.  $compteur += (ord($code{2}) - 64)*pow(26,5);
  25.  $compteur += (ord($code{3}) - 64)*pow(26,4);
  26.  $compteur += (ord($code{4}) - 64)*pow(26,3);
  27.  $compteur += (ord($code{5}) - 64)*pow(26,2);
  28.  $compteur += (ord($code{6}) - 64)*pow(26,1);
  29.  $compteur += (ord($code{7}) - 64)*pow(26,0);
  30.  return compteur2alpha ($compteur+1);
  31. }
  32. return false;
  33. }
  34. //code_suivant("MGMS" ) => "MSMT"  
  35. ?>


 
L'essai donne 233577 => MGMS, 233578 => MGMT


Message édité par T509 le 24-06-2004 à 10:50:08

---------------
fermez vos topics résolus avec le tag [Résolu] en fin de titre. Merci !
Reply

Marsh Posté le 22-05-2004 à 17:39:04    

Je crois ca pourrais etre l'occasion pour moi de me lancer dans la prog objet en php (une tite class avec des methodes genre codeSuivant, codePrecedent, etc etc ... :) )

Reply

Marsh Posté le 22-05-2004 à 17:39:11    

function lettreSuivante :D jaime bien qd jvois ca qd mm

Reply

Marsh Posté le 22-05-2004 à 17:46:14    

red faction a écrit :

function lettreSuivante :D jaime bien qd jvois ca qd mm


 
Je donne toujours des nom explicites  :D
 
edit: en relisant ma fonction je m'dis que j'aurais pu faire des: case 'A': return 'B'; :o


Message édité par aspegic500mg le 22-05-2004 à 17:47:19
Reply

Marsh Posté le 22-05-2004 à 17:49:18    

Code :
  1. function lettreSuivante($actuelle) {
  2.     $actuelle = ($actuelle == "Z" ) ? "@" : $actuelle;
  3.     return chr(ord($actuelle)+1);
  4. }


 
fait la même chose


Message édité par T509 le 22-05-2004 à 17:58:25

---------------
fermez vos topics résolus avec le tag [Résolu] en fin de titre. Merci !
Reply

Marsh Posté le 22-05-2004 à 17:54:54    

T509 a écrit :

Code :
  1. function lettreSuivante($actuelle) {
  2. $actuelle = ($actuelle == "X" ) ? "@" : "$actuelle;
  3. return chr(ord($actuelle)+1);
  4. }


 
fait la même chose


 
je ne comprend pas la premiere ligne  :pt1cable: (le "@" je n'ai jamais utilisé, ca fonctionne comment?)
 
La deuzieme ok, c'est une bonne idée, par contre est-ce que les A-Z se suivent bien? (pour le Z faut penser à revenir au A parce que sinon ca part dans des caracteres ascii qui ne nous interressent plus :) )

Reply

Marsh Posté le 22-05-2004 à 17:54:54   

Reply

Marsh Posté le 22-05-2004 à 17:57:30    

je remplace la lettre "Z" par le caractère "@" car dans la table ascii, il est juste avant le "A".  
code ascii "@" => 64
code ascii "A" => 65
 
Oups, c'est pas "X" mais "Z"


---------------
fermez vos topics résolus avec le tag [Résolu] en fin de titre. Merci !
Reply

Marsh Posté le 22-05-2004 à 18:06:01    

$lettre = 'a';
$lettre++;
-> $lettre = b
 
si $lettre = z au debut, $lettre = aa a la fin ...
 
ca simplifie pas mal ton code ;)
 
ps: si tu mets en majuscules $lettre au debut, meme comportement mais en majuscules.

Reply

Marsh Posté le 22-05-2004 à 18:10:14    

ok t509, je comprend mieux :jap:  
 
 
$lettre++ je pensais pas que ca fonctionnais :ouch:  
 
par contre si lettre est 'acf' et que je fais $lettre++ ca donne 'acg' ? :??:

Reply

Marsh Posté le 22-05-2004 à 18:19:02    

Je me suis amusé à corriger mon code pour aller jusque 8 caractères
;)


---------------
fermez vos topics résolus avec le tag [Résolu] en fin de titre. Merci !
Reply

Marsh Posté le 22-05-2004 à 18:22:28    

T509 a écrit :

Je me suis amusé à corriger mon code pour aller jusque 8 caractères
;)


 
Quand j'aurai le temps je ferai une version illimitée en nombre de caractère (et en reprenant les méthodes plus simples exposées ici :D )

Reply

Marsh Posté le 22-05-2004 à 18:24:03    

oui aspegic

Reply

Marsh Posté le 22-05-2004 à 18:27:07    

aspegic500mg a écrit :

Quand j'aurai le temps je ferai une version illimitée en nombre de caractère (et en reprenant les méthodes plus simples exposées ici :D )


 
avec 8 lettres, cela fait 208 milliards de combinaisons, cela en fait pas mal des codes ...
Tu vas tout utiliser ? ;)


---------------
fermez vos topics résolus avec le tag [Résolu] en fin de titre. Merci !
Reply

Marsh Posté le 22-05-2004 à 18:28:30    

T509 a écrit :

avec 8 lettres, cela fait 208 milliards de combinaisons, cela en fait pas mal des codes ...
Tu vas tout utiliser ? ;)


 
 
ouais aprés je vais gérer des doubles :o (genre j'ai que ca à foutre de faire ca avec des lettres :D )

Reply

Marsh Posté le 22-05-2004 à 18:33:24    

Code :
  1. $lettre = 'A';
  2. for ($i=0;$i<10;$i++)
  3. echo $lettre++;


 
10, c'est le nombre de lettres a afficher. Tu fais un code de ce genre et ton truc est torché en 10 lignes :D

Reply

Marsh Posté le 22-05-2004 à 18:47:45    

l'incrément doit pouvoir se faire avec une petite fonction récursive ...
genre une fonction lettreSuivanteRec qui fait :

Code :
  1. - récupération de la dernière lettre
  2. - si deniereLettre = 'Z' :
  3.   - renvoyer lettreSuivanteRec(chaîne précédant la dernière lettre) concaténé avec deniereLettre
  4. - sinon :
  5.   - renvoyer chaîne (précédant la dernière lettre)concaténé avec deniereLettre++

Reply

Marsh Posté le 23-05-2004 à 02:59:03    

Beegee a écrit :

l'incrément doit pouvoir se faire avec une petite fonction récursive ...
genre une fonction lettreSuivanteRec qui fait :

Code :
  1. - récupération de la dernière lettre
  2. - si deniereLettre = 'Z' :
  3.   - renvoyer lettreSuivanteRec(chaîne précédant la dernière lettre) concaténé avec deniereLettre
  4. - sinon :
  5.   - renvoyer chaîne (précédant la dernière lettre)concaténé avec deniereLettre++




 
Comme ceci ?
 

Code :
  1. <?php
  2. fonction Code_Lettres_Suivant ($code) {
  3. $code = strtoupper ($code);
  4. $long = strlen($code)
  5. if ($long == 0) {
  6.  return "";
  7. }
  8. else {
  9.  if ($code{$long-1} == "Z" ) {
  10.   return Code_Lettres_Suivant(substr($code, 0, $long-1))."A";
  11.  }
  12.  else {
  13.   return $code++;
  14.  }
  15. }
  16. }
  17. ?>


 
Je le trouve amusant ce topic  ;)


Message édité par T509 le 24-05-2004 à 11:03:20

---------------
fermez vos topics résolus avec le tag [Résolu] en fin de titre. Merci !
Reply

Marsh Posté le 23-05-2004 à 09:46:14    

le dernier return devrait plutôt être :
 

Code :
  1. return substr($code, 0, $long-1)).(($code{$long})++);

Reply

Marsh Posté le 23-05-2004 à 16:14:42    

Beegee a écrit :

le dernier return devrait plutôt être :
 

Code :
  1. return substr($code, 0, $long-1)).(($code{$long})++);




 
Pas forcément puisque  
$code = "abc";
$code ++ => "abd"


---------------
fermez vos topics résolus avec le tag [Résolu] en fin de titre. Merci !
Reply

Marsh Posté le 23-05-2004 à 22:42:22    

T509 a écrit :

Pas forcément puisque  
$code = "abc";
$code ++ => "abd"


 
je croyais que ça ne marchait qu'avec une lettre :)

Reply

Marsh Posté le 24-05-2004 à 22:10:25    

Et bah ca a bien avancé, merci pour cette solution bien plus simple :jap:

Reply

Marsh Posté le 25-05-2004 à 00:16:19    

On devrait peut être lancer parfois des petites "joutes de code", qu'en pensez vous ?
On fixe un énoncé, on donne un temps de résolution. L'énoncé est prévu pour un travail d'une heure environ.
 
Cela pourrait être amusant et je suis sûr qu'on pourrait apprendre pas mal de choses.


---------------
fermez vos topics résolus avec le tag [Résolu] en fin de titre. Merci !
Reply

Marsh Posté le 25-05-2004 à 01:59:16    

T509 a écrit :

On devrait peut être lancer parfois des petites "joutes de code", qu'en pensez vous ?
On fixe un énoncé, on donne un temps de résolution. L'énoncé est prévu pour un travail d'une heure environ.
 
Cela pourrait être amusant et je suis sûr qu'on pourrait apprendre pas mal de choses.


 
Oui mais il ne faudrait pas qu'un cador arrive et donne la solution au bout de 5 minutes avant qu'on ait eu le temps de chercher !
 
Ca me semble interressant comme idée, par contre faut trouver des énoncées interressantes :o  :)  
 
 
ps: si c'est pour une sorte de concours il faut un endroit où chacun peut poster son code au fur et à mesure, sans pouvoir éditer et où les autres ne peuvent pas voir le code avant la fin du concours, et on regarde à la fin ce que chacun à fait :pt1cable:  
 

Reply

Marsh Posté le 25-05-2004 à 02:45:16    

aspegic500mg a écrit :

Oui mais il ne faudrait pas qu'un cador arrive et donne la solution au bout de 5 minutes avant qu'on ait eu le temps de chercher !
 
Ca me semble interressant comme idée, par contre faut trouver des énoncées interressantes :o  :)  
 
 
ps: si c'est pour une sorte de concours il faut un endroit où chacun peut poster son code au fur et à mesure, sans pouvoir éditer et où les autres ne peuvent pas voir le code avant la fin du concours, et on regarde à la fin ce que chacun à fait :pt1cable:


 
Pour les ennoncés, ton compteur est un bel exemple. Il y a déjà eu 3 propositions différentes
 
C'est à chacun d'être honnete, et de ne pas aller pomper sur les autres. Ou alors le but peut aussi être de proposer chacun des solutions différentes volontairement.


Message édité par T509 le 25-05-2004 à 02:46:47

---------------
fermez vos topics résolus avec le tag [Résolu] en fin de titre. Merci !
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed