toutes les permutations d'une chaine de charatere [algo] - Algo - Programmation
Marsh Posté le 10-03-2005 à 23:53:55
(flag)
A premiere vue je ne crois pas avoir deja vu d'algo non récursif explorant n! possibilités.....
Marsh Posté le 11-03-2005 à 00:46:45
bon je viens de pondre une idée, par contre ca me saoul a implementer (quoi que peut etre on verra)
pour une chaine de N char.
il faut faire parcourrir i de 1 a N!
decomposer i en:
a1*(n-1)! + a2*(n-2)! + ... + an
et puis les (a)n peuvent faire une bijection des characteres de la chaine
Marsh Posté le 11-03-2005 à 00:59:04
simple mais pas non récursif (edit: et meme pas juste d'ailleurs )
faire autant de fois que de lettres |
Marsh Posté le 11-03-2005 à 02:53:33
ayé ca marche en non reccursif
>art_dupond:
autant de fois qu'il y a de lettres comment on arrive a n! alors??
Marsh Posté le 11-03-2005 à 08:40:19
slvn a écrit : bon je viens de pondre une idée, par contre ca me saoul a implementer (quoi que peut etre on verra) |
Ouais, c'est cette méthode que j'ai utilisée (pour un autre problème).
En revanche il faut faire attention au type que tu utilises pour tes entiers car 12 ! = 479 001 600 mais 13! = 6 227 020 800.
Marsh Posté le 11-03-2005 à 09:58:50
slvn a écrit : ayé ca marche en non reccursif |
j'ai pas compris. Pourquoi je dois arriver à n! ?
ah ok j'ai compris...
euh... 2 sec
re-edit: bon je ne trouve plus comment ca marchait. Là c'est sûr que c'est pas bon
Marsh Posté le 11-03-2005 à 11:14:29
Sinon de manière recursive, est-ce que y a moyen simple comme tu le dis art_dupond ??
(ie, sans passer par une arbre ou il y aurait n choix au level 1, n-1 choix au level 2, etc..)
Marsh Posté le 12-03-2005 à 19:35:56
J'ai fait ce que tu cherches en itératif, je vais le chercher dans mon bordel...
Marsh Posté le 12-03-2005 à 20:29:54
Ouf, c'est bon
bon, le truc est en C mais l'algo est court et pas compliqué (c'est juste la boucle de 20 lignes qui est intéressante) :
Code :
|
PS : évidemment, si il y a des répétitions dans la chaîne de caractères, j'ai pas trouvé mieux que de tout classer par ordre alphabétique (ou faire un arbre à la limite) pour virer les doublons
Marsh Posté le 13-03-2005 à 00:11:56
Et recursif à l'ordre superieur ?
Mais avec les repetitions
Citation : |
Quelqu'un est chaud pour l'ecrire en ML ou Haskell ? ... avec les Monads ?
Marsh Posté le 13-03-2005 à 01:52:45
oulala je capte rien ni au premier ni au deuxieme
(pt etre que je suis pas en etat la )
>leneuf22
pour l'iteratif, en fait je l'ai deja fait. Mais le mien est beaucoup plus long
tu peux expliquer un peu ta boucle
>Chronoklaz
euh c'est quoi le langage la j'ai l'impression que la police de caractere passe mal chez moi
Marsh Posté le 13-03-2005 à 09:37:25
OK, je vais tenter de t'expliquer :
Déjà, si le nombre de lettres était fixé, par exemple 5 lettres, l'algo pourrait se traduire en 5 boucles for imbriquées, ça aurait été beaucoup plus facile.
Or ici, le nombre de lettres n'est pas fixé, il faut donc s'adapter :
boucle comme son nom l'indique, joue le role d'un tableau de boucles for.
Ce code fait donc exactement l'effet de x boucles for imbriquées, au détail près que l'on ne connait pas x.
(boucle contient un nombre d'éléments égal nombre de lettres entrées)
Ensuite, pour générer toutes les permutations possibles, j'avais trouvé que de simples rotations suffisaient :
Pour que tu comprennes mieux, si on avait nos x boucles for imbriquées, il faudrait faire une rotation des n+1 derniers caractères à chaque fois que l'on sort de la boucle n (j'appelle la boucle la plus globale la boucle x, et la moins globale la boucle 1 : au sortir de la boucle 1 (qui n'est pas vraiment une boucle puisqu'elle ne se répète qu'une seule fois), on fait une rotation des 2 derniers caractères. Le sens importe peu, il faut juste que ça soit le même à chaque fois). Ce système de rotations suffit à obtenir toutes les permutations.
Ensuite, tu auras remarqué que le tableau "boucle" contient des valeurs. En fait, il contient pour chaque boucle le compteur de celle-ci. La première boucle (boucle[0]) est initialisée une seule fois au nombre de caractères x, et les autres seront initialisées à x-1, x-2... 1 : on retrouve bien x(x-1)(x-2)...(1) = x!. Il faut juste réinitialiser le compteur de chaque boucle quand on y entre.
Code :
|
EDIT (un peu tardif) : j'ai viré mes conneries
Marsh Posté le 13-03-2005 à 09:51:32
Heu, sinon, Chronoklazm et moi on n'a pas compris le problème de la même façon apparemment...
Le code de Chronoklazm donne n^n réponses (toutes les combinaisons possibles, sans notion d'ordre), et le mien en donne n! (toutes les permutations possibles), ce n'est pas tout à fait pareil.
Marsh Posté le 13-03-2005 à 12:06:04
Arf, avais trop bu moi ! Mais la fonction words me plait bien
Citation : |
PS: slvn => C'est un dialecte de Lisp.
Marsh Posté le 13-03-2005 à 14:45:04
>leneuf22
oky j'ai capté l'aglo,
solution très élégante
>Chronoklazm
..bon pour le lisp, j'ai du mal avec la syntaxe donc je laisse tomber
sylvain
Marsh Posté le 13-03-2005 à 16:29:50
Content de t'avoir aidé
(je viens de me rendre compte que je pouvais faire mieux encore, j'ai édité mes posts plus haut : tu remarqueras qu'avec un while supplémentaire c'est encore plus élégant :-) )
Marsh Posté le 13-03-2005 à 16:32:39
Code :
|
Marsh Posté le 13-03-2005 à 16:37:24
Là on ne peut pas faire mieux que ca, je pense.
Marsh Posté le 13-03-2005 à 16:41:50
En même temps on est dans le forum algo, donc utiliser ça, ça répond pas à la question...
Marsh Posté le 13-03-2005 à 16:44:23
On va pas reinventer la roue c'est sur ... enfin qui sait
Marsh Posté le 13-03-2005 à 16:50:04
leneuf...
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
!
Marsh Posté le 13-03-2005 à 16:57:55
Et alors ? J'utilise le minimum qu'un système d'exploitation est sensé nous offrir (les E/S et la mémoire) : ce que j'ai fait est traduisible dans plein de langages, ton truc non, c'est complètement hors sujet.
On aurait été dans le forum C++ jveux bien, mais là faut pas pousser quand même
Marsh Posté le 13-03-2005 à 17:07:54
mouarf CodeGuard signale des dépassements d'accès sur ton code.
Marsh Posté le 13-03-2005 à 17:11:52
Oups, 'me suis planté dans le calloc en effet, mettre longueurchaine à la place de maxcurseur
Ce genre de remarques est déjà plus constructif :-)
(j'ai édité)
Marsh Posté le 13-03-2005 à 17:36:29
C'est ce que je disais plus haut, mon truc génère des doublons si il y a des caractères multiples.
Faut voir avec slvn si il veut prendre en compte ce cas, mais à part virer les doublons avec une recherche exhaustive, après la génération des résultats, je ne vois vraiment pas comment procéder.
Si il y a un "truc", ça m'intéresserait de le connaître, mais je pense que c'est déjà beaucoup plus complexe.
Marsh Posté le 13-03-2005 à 17:53:50
meme si c'est pas ce que je souhaitais,
j'aime bien la solution de fra0
>a priori gerer toutes les permutations, ca voudrait dire enlever les doublons. avec ton algo c'est pas possible a gerer facilement.
Marsh Posté le 13-03-2005 à 18:19:41
voila ce que j'ai fait, ca doit etre quasiment comme leneuf22, en tt cas c'est le meme principe , et ca gere pas non plus les doublons
Code :
|
[edit];ajout de "free(nb);" ^^
Marsh Posté le 13-03-2005 à 20:11:20
manque un free nan ?
Code :
|
Marsh Posté le 13-03-2005 à 20:33:59
Excellent, je mets ça de côté
Tu pourrais expliquer comment ton code marche ? Je ne comprends absolument la subtilité de cet algo ...
(sinon, pour le code de Dark86, ya pas que le free manquant qui va pas... enfin on est sur le forum algo alors on dira rien )
Marsh Posté le 13-03-2005 à 20:42:06
lol, mouai, les free....
m'enfin il donne la liste voulue, c'est ce qu'on lui demande^^
Marsh Posté le 14-03-2005 à 01:31:36
cf docs
à partir d'un mot,
ça revient à trouver le mot suivant dans l'ordre lexicographique
qui utilise les mêmes lettres...
je suis sûr que tu peux résoudre ce problème.
Marsh Posté le 10-03-2005 à 19:01:38
Bonjour,
Est-ce que vous connaissez un algo simple, non récursif, pour afficher toutes les permutations d'une chaine de charatere.
Sylvain