Je voudrais savoir quand on a une valeur exemple 101010 combien de 1 il y a içi 3 et je n'arrive pas a le faire pour mon programme si quelqu'un peut m'aider
Version imprimable
Je voudrais savoir quand on a une valeur exemple 101010 combien de 1 il y a içi 3 et je n'arrive pas a le faire pour mon programme si quelqu'un peut m'aider
Code:
1
2
3
4
5
6
7
8
9
10
11
12 AnsiString buffer = "10011001" ; int compteur=0; for(int i=1; i <= buffer.Length(); i++) { if( buffer[i] == '1' ) { compteur = compteur + 1 ; } } ShowMessage( "Il y a " + IntToStr( compteur ) + " fois le chiffre '1' dans " + buffer ) ;
Salut !
Code:
1
2AnsiString Chaine = "10101001";
Code:
1
2
3
4
5
6
7
8 int Ones(AnsiString N) { int n = 0; int max = N.Length() + 1; for(int j = 1; j < max; j++) n = n + (N[j] == '1'); return n; }
Code:
1
2 Label1->Caption = Ones(Chaine);
Autre solution :
Code:
1
2 int Valeur = 0xC9;
Code:
1
2
3
4
5
6
7
8
9
10
11 int Ones(int N) { int n = 0; for(int j = 0; j < 32; j++) { n = n + (N & 1); N = N / 2; // ou N = N >> 1; } return n; }
A plus !
la réponse est là. Avec 5 opérations au lieu d'une boucle de 32 itérations...
Salut !
Le plus optimisé passe par un Tableau ( Byte Ones[256] ) donc à initialiser...
Pour un Byte, c'est une simple lecture du tableau (il n'y a pas plus rapide)
Pour un short, c'est l'addition de deux lectures du tableau
Pour un int, c'est l'addition de quatre lectures du tableau
Comme ici on est très près de la machine (C, C++), on a intérêt à suggérer au compilateur de travailler au niveau du Byte (struct + union) pour accéder aux bytes du int sans faire glisser quoique ce soit.
Par contre... vérifier si le µ ne sait pas le faire... avec une seule instruction machine !
C'est un peu comme le parity/odd pour lequel on peut s'amuser à tirer un algorithme mais qui existe sous forme de flag dans le registre cpu (résultat du cablage physique d'un parity tree) ! Non ?
Donc si c'est amusant à faire d'un point de vue algorithmique, ça n'en demeure pas moins ridicule face à d'autres solutions (en termes de rapidité d'exécution) !
Et comme ici je ne sais pas à qui j'ai à faire ni dans quel domaine on est, j'ai donné ce qu'il y a de plus simple (même si c'est poussif !!!) !
A plus !
Est-ce que le problème est :resolu: ou non?
Salut !
Voici la solution avec un tableau :
Qu'on se rassure... c'est un algo qui m'a généré ce tableau dans un fichier TXT !Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 Byte Ones[256] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4, 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8};
Donc chez moi, on trouve :
Ensuite on se sert d'une union pour y stocker les valeur à traiter.Code:
1
2 #include "Ones.Txt"
Au cas où l'on retrouverait le scripte un peu partout dans le code (pourquoi pas) :Code:
1
2
3
4
5 union{Byte B[4]; unsigned short S[2]; int I; } u;
Le comptage se fait simplement (encore mieux lorsque le compilateur optimise l'adressage : nous on a besoin de l'union mais pas l'assembleur qui est derrière le compilateur !Code:
1
2
3
4
5 #define b0 Ones[u.B[0]] #define b1 Ones[u.B[1]] #define b2 Ones[u.B[2]] #define b3 Ones[u.B[3]]
Pour info, voici le traitement que j'ai utilisé pour générer le tableau dans un fichier TXT :Code:
1
2
3
4
5
6
7
8
9
10
11 // Au niveau du byte c'est assez implicite : Label1->Caption = Ones[0xf0]; // Au niveau du short : u.S[0] = 0x0101; Label2->Caption = b0 + b1; //Au niveau du int : u.I = 0xffffffff; // -1 Label3->Caption = b0 + b1 + b2 + b3;
(c'est bateau ... mais comme il n'apparaîtra jamais nulle part... sauf sur ce forum)
Mais bon... chacun fait bien comme court lui semble !Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 int OneDigit(int n) { int d = (n & 1); n = n >> 1; d = d + (n & 1); n = n >> 1; d = d + (n & 1); n = n >> 1; d = d + (n & 1); return d; } void CreateOnes(AnsiString Filename) { int b; TStringList *Fichier = new TStringList; AnsiString N = "Byte Ones[256] = {"; for(int j = 0; j < 16; j++) { b = OneDigit(j); if(j != 0) N = ""; for(int i = 0; i < 16; i++) { N = N + IntToStr(b + OneDigit(i)); if((j == 15) && (i == 15)) N = N + "};"; else N = N + ","; } Fichier->Add(N); } Fichier->SaveToFile(Filename); delete Fichier; }
A plus !