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
"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.
"Mickaël Wolff" <mickael.wolff@laposte.net> a écrit dans le message de news:
473d63c1$0$31712$426a74cc@news.free.fr...
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.
"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.
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
En news:473d6621$0$2202$426a34cc@news.free.fr, Charlie Gordon va escriure:
Mickaël Wolff a écrit dans le message de news:
473d63c1$0$31712$426a74cc@news.free.fr...
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.
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
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
En news:473c8f27$0$6137$426a34cc@news.free.fr, 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 ;-)
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
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
En news:fhicbr$2i6d$1@biggoron.nerim.net, 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.
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
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.
On 15 nov, 19:07, es...@lain.home (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);
}
}
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; }
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.
"candide" <c-candide@wanadoo.fr> a écrit dans le message de news:
7578077f-bedb-4fa6-ae86-e11211ce76d9@f13g2000hsa.googlegroups.com...
On 15 nov, 19:07, es...@lain.home (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";
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.
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.
"Antoine Leca" <root@localhost.invalid> a écrit dans le message de news:
fhju75$u1g$1@shakotay.alphanet.ch...
En news:473c8f27$0$6137$426a34cc@news.free.fr, 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.
"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.
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...
In article <473e0559$0$14273$426a74cc@news.free.fr>,
Charlie Gordon <news@chqrlie.org> 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...
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...
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
In article <473e0559$0$14273$426a74cc@news.free.fr>,
Charlie Gordon <news@chqrlie.org> 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
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