OVH Cloud OVH Cloud

Combinaison min/MAJ

43 réponses
Avatar
spongebof
Bonjour,

Je cherche un algorithme à implémenter en C qui soit capable à partir
d'un mot de X caractères de trouver toutes les écritures possibles pour
0 à X majuscule(s) présente(s) dans ce mot.

Exemple pour le mot 'test':

test
tesT
teSt
teST
tEst
tEsT
tESt
tEST
Test
TesT
TeSt
TeST
TEst
TEsT
TESt
TEST

Merci

10 réponses

1 2 3 4 5
Avatar
Charlie Gordon
"Mickaël Wolff" a écrit dans le message de news:
473d63c1$0$31712$

Complément à la réponse d'hier soir que j'ai écrit en courant.


[snip]

Le résultat global n'est pas très cohérent, et c'est bien la conclusion à
laquelle Mickaël était arrivé.


Merci pour tout ces éclaircissements ! Tout ceci me fait penser qu'au
final, il est plus intelligent d'utiliser des wchar en lieu et place des
char. Non ? (même si en fait, les wchar sont des int déguisés).


En fait c'est le meme merdier en plus compliqué : wchar_t peut être signé ou
non signé comme char, et sa taille varie d'un système à l'autre alors que
char est généralement un octet, soit 8 bits.

--
Chqrlie.


Avatar
Antoine Leca
En news:473d6621$0$2202$, Charlie Gordon va escriure:
Mickaël Wolff a écrit dans le message de news:
473d63c1$0$31712$

Tout ceci me fait penser
qu'au final, il est plus intelligent d'utiliser des wchar en lieu et
place des char. Non ? (même si en fait, les wchar sont des int
déguisés).


En fait c'est le meme merdier en plus compliqué : wchar_t peut être
signé ou non signé comme char, et sa taille varie d'un système à
l'autre alors que char est généralement un octet, soit 8 bits.


Sans compter qu'avec toupper() et tolower() on sait à peu près où l'on va,
et on peut se satisfaire de l'approximation charÊractère.
Avec wchar_t il devient idiot de ne pas considérer Unicode, et là on
s'apperçoit bien vite qu'un caractère n'est pas réductible à un wchar_t, en
tous cas lorsque l'on manipule de propriétés comme la casse. Unicode (le
consortium) demande d'ailleurs à ce que ce genre de manipulations soit
faites en considérant des chaînes de caractères, et qui plus est en
rajoutant des notions contextuelle de langue.

Et si tu vas par là, bin t'es pas sorti de l'auberge pour générer toutes les
variantes de casse. Tout cela pour un simple exercice de TP, non vraiment
cela n'en vaut pas la peine.


Antoine


Avatar
Antoine Leca
En news:473c8f27$0$6137$, Charlie Gordon va escriure:
for(index=0; index < total; index++)



Oui, c'et pourquoi je préconise unsigned long.


Et tu lui laisses la boucle infinie (la comparaison de non-signés, un de tes
dadas) ! Méchant Chqrlie ;-)


Antoine



Avatar
Antoine Leca
En news:fhicbr$2i6d$, Marc Espie va escriure:
apres tout, ils ne se sont pas genes pour index -> strchr.


Petite erreur historique de ta part.
index() a été remplacé (pour des raisons que j'ignore) dans le code ATT par
strchr(). Et le comité ANSI a seulement considéré the document de /usr/group
pour la bibliothèque, c'est-à-dire les documents de l'implémentation ATT
(future SVID), qui étaient (et de loin) le plus utilisable de ce qui
existait à l'époque. Le comité ANSI a ignoré peu ou prou BSD, probablement
parce que les objectifs divergaient suffisament à l'époque.

Le comité POSIX est parti de la même base, mais eux ont (bien obligés)
incorporé l'héritage BSD.


Antoine

Avatar
candide
On 15 nov, 19:07, (Marc Espie) wrote:
#include <stdio.h>
#include <ctype.h>

void
enumere(char *m, int i)
{
if (m[i] == 0)
puts(m);
else {
m[i] = tolower(m[i]);
enumere(m, i+1);
if (m[i] != toupper(m[i])) {
m[i] = toupper(m[i]);
enumere(m, i+1);
}
}

}



Comme on dit :

Iteration is human but recursion is divine.

Avatar
candide
On 15 nov, 19:07, (Marc Espie) wrote:
Tiens, je me repond a moi-meme, on peut faire le travail en place, et
eviter un probleme subtil.

#include <stdio.h>
#include <ctype.h>

void
enumere(char *m, int i)
{
if (m[i] == 0)
puts(m);
else {
m[i] = tolower(m[i]);
enumere(m, i+1);
if (m[i] != toupper(m[i])) {
m[i] = toupper(m[i]);
enumere(m, i+1);
}
}

}

int
main()
{
/* necessaire pour eviter une chaine constante */
char mot[] = "court-circuit";

enumere(mot, 0);
return 0;

}


D'ailleurs, il me semble qu'on peut encore un peu épurer :

#include <stdio.h>
#include <ctype.h>

void enumere(char *m, int i)
{
if (m[i] == 0)
puts(m);
else
{
enumere(m, i + 1);
m[i] = toupper(m[i]);
enumere(m, i + 1);
m[i] = tolower(m[i]);
}
}

int main()
{
/* necessaire pour eviter une chaine constante */
char mot[] = "court";

enumere(mot, 0);
return 0;
}

Avatar
Charlie Gordon
"candide" a écrit dans le message de news:

On 15 nov, 19:07, (Marc Espie) wrote:
Tiens, je me repond a moi-meme, on peut faire le travail en place, et
eviter un probleme subtil.

#include <stdio.h>
#include <ctype.h>

void
enumere(char *m, int i)
{
if (m[i] == 0)



je préfère ``if (m[i] == '')'' et j'utilise des {} pour les deux branches
du if, enfin les conventions d'indentation de Gnu sont immondes.

puts(m);
else {
m[i] = tolower(m[i]);



m[i] = tolower((unsigned char)m[i]);

enumere(m, i+1);
if (m[i] != toupper(m[i])) {
m[i] = toupper(m[i]);



if (m[i] != toupper((unsigned char)m[i])) {
m[i] = toupper((unsigned char)m[i]);

enumere(m, i+1);
}
}

}

int
main()
{
/* necessaire pour eviter une chaine constante */
char mot[] = "court-circuit";

enumere(mot, 0);
return 0;

}


D'ailleurs, il me semble qu'on peut encore un peu épurer :


Mais il faut aussi corriger les problèmes ;-) et éviter d'en rajouter,
ou plus précisément de changer la sémantique en supprimant des
fonctionnalités. Le test supplémentaire dans enumère permet de
supporter des mots qui contiennent des caractères non alphabétiques
sans générer de doublons.

#include <stdio.h>
#include <ctype.h>

void enumere(char *m, int i)
{
if (m[i] == 0)
puts(m);
else
{
enumere(m, i + 1);
m[i] = toupper(m[i]);
enumere(m, i + 1);
m[i] = tolower(m[i]);
}
}

int main()
{
/* necessaire pour eviter une chaine constante */
char mot[] = "court";

enumere(mot, 0);
return 0;
}


--
Chqrlie.


Avatar
Charlie Gordon
"Antoine Leca" a écrit dans le message de news:
fhju75$u1g$
En news:473c8f27$0$6137$, Charlie Gordon va escriure:
for(index=0; index < total; index++)



Oui, c'et pourquoi je préconise unsigned long.


Et tu lui laisses la boucle infinie (la comparaison de non-signés, un de
tes
dadas) ! Méchant Chqrlie ;-)


Pas du tout, je dis plus haut qu'il faudrait aussi tester la valeur de N
pour éviter le comportement indéfini, et qu'il faut le même type pour index
et total.

J'ai par ailleurs posté une version complète (un peu alambiquée) dont Marc
Espie a critiqué mon utilisation de strdup.

--
Chqrlie.




Avatar
espie
In article <473e0559$0$14273$,
Charlie Gordon wrote:
m[i] = tolower((unsigned char)m[i]);


Euh, le cast en question, c'est la bibliotheque C qui est censee le
faire en interne... du point de vue utilisateur, tolower() prend
specifiquement un int pour qu'il n'y ait pas de probleme de coercion
du caractere mal venue...

Avatar
Aris
In article <473e0559$0$14273$,
Charlie Gordon wrote:
m[i] = tolower((unsigned char)m[i]);


Euh, le cast en question, c'est la bibliotheque C qui est censee le
faire en interne... du point de vue utilisateur, tolower() prend
specifiquement un int pour qu'il n'y ait pas de probleme de coercion
du caractere mal venue...
de manière générale, jamais faire de cast explicite là où le cast

implicite fonctionne. C'est la porte ouverte à des conversions invalides
qui peuvent prendre des heures à débugger


1 2 3 4 5