Page 1 sur 4
[Résolu] Permutation de groupes de caractères
Publié : lun. 22/févr./2016 17:43
par Micoute
Bonjour à tous,
sur le principe de mon code ci-joint, je voudrais faire permuter des groupes de caractères pas forcément de même longueurs du genre : "200~158~75~25" où les tildes séparent chaque groupes pour faire des suites du genre : 25~158~75~200, 158~25~75~200, 75~158~25~200, 200~158~75~25, etc...
Code : Tout sélectionner
BASE_PERM$="1234" ;Régler la bases des Permutations
Debug "Permutations possibles de : " + BASE_PERM$
Dim COMPTEUR_PERM.l(Len(BASE_PERM$)+1)
While BASE_PERM$>""
; MessageRequester("",BASE_PERM$)
PERM$ = BASE_PERM$
BASE$ = Left(BASE_PERM$,1) +"~"
For i = 2 To Len(BASE_PERM$) - 1
BASE$ + Mid(BASE_PERM$,i,1)+"~"
Next i
BASE$ + Right(BASE_PERM$,1)
Debug BASE$
Gosub PERMUTATION
Wend
End
;========== la Routine ==========
PERMUTATION:
If POS_PERM.l=0
COMPTEUR_PERM.l=0
QUEUE_PERM$=""
LONG_PERM.l = Len(BASE_PERM$)
EndIf
POS_PERM.l = 1
NIVEAU_PERMUT:
If COMPTEUR_PERM.l(POS_PERM.l)>=POS_PERM.l
PERM_P.l = POS_PERM.l+1
While Asc(QUEUE_PERM$)<PERM_P.l And QUEUE_PERM$>""
POS_PERM.l = Asc(QUEUE_PERM$)
QUEUE_PERM$ = Right(QUEUE_PERM$,Len(QUEUE_PERM$)-1)
Gosub CHANGE_PERMUT
Wend
POS_PERM.l = PERM_P.l
While PERM_P.l
PERM_P.l = PERM_P.l-1
COMPTEUR_PERM.l(PERM_P.l) = 0
Wend
If POS_PERM.l<LONG_PERM.l
Goto NIVEAU_PERMUT
EndIf
BASE_PERM$=""
POS_PERM.l=0
Return
EndIf
Gosub CHANGE_PERMUT
QUEUE_PERM$ = Chr(POS_PERM.l)+QUEUE_PERM$
COMPTEUR_PERM.l(POS_PERM.l) = COMPTEUR_PERM.l(POS_PERM.l)+1
Return
CHANGE_PERMUT:
BASE_PERM$ = Mid(BASE_PERM$,POS_PERM.l+1,1)+Left(BASE_PERM$,POS_PERM.l)+Right(BASE_PERM$,Len(BASE_PERM$)-(POS_PERM.l+1))
Return
Re: Permutation de groupes de caractères
Publié : lun. 22/févr./2016 17:58
par Shadow
Salut Micoute,
Tu veux calculer toutes les permutations des "Groupe" possible c'est ça ?
Ex:
Permutations possibles de : 125 ~ 214 ~ 38
125 ~ 214 ~ 38
214 ~ 125 ~ 38
38 ~ 125 ~ 214
125 ~ 38 ~ 214
214 ~ 38 ~ 125
38 ~ 214 ~ 125
Re: Permutation de groupes de caractères
Publié : lun. 22/févr./2016 18:00
par Micoute
Oui, bien sûr, mais je ne sais pas comment le faire !
Re: Permutation de groupes de caractères
Publié : lun. 22/févr./2016 18:04
par Shadow
Dis moi Micoute, combien de "Groupe" doit gérer ton algorithme ?
10, 100, 1000 ?
L'algo dois en gros calculer toutes les permutations
des dit "Groupe" si j'ai bien compris ?
Tu sais que plus y aura de groupe et plus se serra long !
Re: Permutation de groupes de caractères
Publié : lun. 22/févr./2016 18:09
par Micoute
Oui, bien entendu, mais en fait la limite, c'est la mémoire qui l'impose car elle n'est pas illimitée, sinon je pense qu'on pourrait aller jusqu'à plusieurs millions !
Re: Permutation de groupes de caractères
Publié : lun. 22/févr./2016 18:10
par Shadow
Ah ouais quand même

Re: Permutation de groupes de caractères
Publié : lun. 22/févr./2016 18:15
par Marc56
Je ne comprend pas grand chose en algo, mais dans ton exemple, il semble traiter "1234" comme une chaine de caractères (qu'il sépare en 4 caractères), donc pour ton souhait, c'est la même chose: tu découpe ta chaine en 4 éléments que tu met dans un tableau et tu utilises la même formule mais avec les éléments ().
Ça prendra autant de temps quelque soit la longueur des 4 éléments puisque tu ne travaille pas sur leur contenu mais sur leur identifiant.
Et encore moins si tu te sert de pointeurs (mais je n'ai jamais véritablement utilisé les pointeurs)
Stringfield() pour saucissonner la chaine sur les '~'

Re: Permutation de groupes de caractères
Publié : lun. 22/févr./2016 18:34
par Micoute
Merci Marc56,
je travaille déjà sur ce système, mais je vais à l'aveugle, car mon exemple ne travaille qu'avec un seul caractère et le problème c'est que les groupes de caractères n'auront pas les mêmes longueurs.
Pour l'instant, je mets chaque groupe dans un tableau et je compte remplacer les nombres en indices de tableau.
Re: Permutation de groupes de caractères
Publié : lun. 22/févr./2016 19:03
par Micoute
Voici ma solution :
Code : Tout sélectionner
BASE_PERM$ = ""
Base_Groupe$ = "25~158~75~200"
Nb_Groupes = CountString(Base_Groupe$, "~") + 1
Global Dim tableau.s(Nb_Groupes - 1)
For i = 1 To Nb_Groupes
tableau(i - 1) = StringField(Base_Groupe$, i, "~")
BASE_PERM$ + Str(i)
Next i
;BASE_PERM$="1234" ;Régler la bases des Permutations
;Debug "Permutations possibles de : " + BASE_PERM$
Dim COMPTEUR_PERM.l(Len(BASE_PERM$)+1)
While BASE_PERM$>""
; MessageRequester("",BASE_PERM$)
PERM$ = BASE_PERM$
BASE$ = tableau(Val(Left(BASE_PERM$,1))-1)+"~"
For i = 2 To Len(BASE_PERM$) - 1
BASE$ + tableau(Val(Mid(BASE_PERM$,i,1))-1)+"~"
Next i
BASE$ + tableau(Val(Right(BASE_PERM$,1))-1)
Debug BASE$
Gosub PERMUTATION
Wend
End
;========== la Routine ==========
PERMUTATION:
If POS_PERM.l=0
COMPTEUR_PERM.l=0
QUEUE_PERM$=""
LONG_PERM.l = Len(BASE_PERM$)
EndIf
POS_PERM.l = 1
NIVEAU_PERMUT:
If COMPTEUR_PERM.l(POS_PERM.l)>=POS_PERM.l
PERM_P.l = POS_PERM.l+1
While Asc(QUEUE_PERM$)<PERM_P.l And QUEUE_PERM$>""
POS_PERM.l = Asc(QUEUE_PERM$)
QUEUE_PERM$ = Right(QUEUE_PERM$,Len(QUEUE_PERM$)-1)
Gosub CHANGE_PERMUT
Wend
POS_PERM.l = PERM_P.l
While PERM_P.l
PERM_P.l = PERM_P.l-1
COMPTEUR_PERM.l(PERM_P.l) = 0
Wend
If POS_PERM.l<LONG_PERM.l
Goto NIVEAU_PERMUT
EndIf
BASE_PERM$=""
POS_PERM.l=0
Return
EndIf
Gosub CHANGE_PERMUT
QUEUE_PERM$ = Chr(POS_PERM.l)+QUEUE_PERM$
COMPTEUR_PERM.l(POS_PERM.l) = COMPTEUR_PERM.l(POS_PERM.l)+1
Return
CHANGE_PERMUT:
BASE_PERM$ = Mid(BASE_PERM$,POS_PERM.l+1,1)+Left(BASE_PERM$,POS_PERM.l)+Right(BASE_PERM$,Len(BASE_PERM$)-(POS_PERM.l+1))
Return
Re: Permutation de groupes de caractères
Publié : lun. 22/févr./2016 19:29
par Ar-S
Le retour de la revanche de l'anagramme
Et oui, même si ce sont des chiffres, c'est un anagramme que tu souhaites faire.
Re: Permutation de groupes de caractères
Publié : lun. 22/févr./2016 19:35
par cage
Le nombre de combinaison possible est n! (factorielle de n)
Dans l'exemple donné, n vaut 4 (1234), c'est a dire 4 éléments a permuter.
Le nombre d'éléments est le même si on remplace (1234) par (6789) ou par (AGMT)
Le nombre de permutations possible est 4! soit 1*2*3*4 soit 24 combinaisons.
1,2,3,4
1,2,4,3
1,3,2,4
1,3,4,2
1,4,2,3
1,4,3,2
2,1,3,4
2,1,4,3
2,3,1,4
2,3,4,1
2,4,1,3
2,4,3,1
3,1,2,4
3,1,4,2
3,2,3,4
3,2,4,3
3,4,1,2
3,4,2,1
4,1,2,3
4,1,3,2
4,2,1,3
4,2,3,1
4,3,1,2
4,3,2,1
Re: Permutation de groupes de caractères
Publié : lun. 22/févr./2016 19:54
par falsam
cage a écrit :Le nombre de combinaison possible est n! (factorielle de n)
Dans l'exemple donné, n vaut 4 (1234), c'est a dire 4 éléments a permuter.
Le nombre d'éléments est le même si on remplace (1234) par (6789) ou par (AGMT)
Le nombre de permutations possible est 4! soit 1*2*3*4 soit 24 combinaisons.
Exactement Cage.
Il suffit d'utiliser un system de pattern correspondant au nombre d'éléments du groupe
Exemple : Le groupe "25~158~75~200" est composé de 4 éléments séparés par "~"
La pattern sera "1234"
1 Correspond à 25
2 Correspond à 158
3 Correspond à 75
4 Correspond à 200
Lors d'une permutation de pattern, si on obtient "2413"
alors nous aurons le résultat "158~200~25~75"
C'est ce que montre ce code : (
Désactiver le support unicode dans les options de compilation)
Code : Tout sélectionner
;Désactiver le support unicode dans les options de compilation
Procedure.s SetPermutation(Pattern.s, n)
Protected i, Factorial = 1, Temp
For i = 2 To Len(Pattern)
Factorial * (i - 1)
Temp = PeekB(@Pattern + (i - ((n / Factorial) % i) - 1))
PokeB(@Pattern + (i - ((n / Factorial) % i) - 1), PeekB(@Pattern + i - 1))
PokeB(@Pattern + i - 1, Temp)
Next
ProcedureReturn Pattern
EndProcedure
Procedure GetCombination(Groupe.s)
Protected i,j
Protected Pattern.s ;Composer d'une séquence de chiffres (Exemple : 1234)
Protected Permutation.s ;Permutation retournée par la procédure SetPermutation. Exemple (2413)
Protected Result.s ;Résultat à afficher
;Compter le nombre de groupe
;Constituer le pattern correspondant (Exemple "25~158~75~200" donnera 1234)
For i = 1 To CountString(Groupe, "~") + 1
Pattern + Str(i)
Next
;Générer les permutations pour la pattern
i=1
Repeat
Result = ""
Permutation = SetPermutation(Pattern, i)
;Construire le nouveau groupe en fonction de la pattern obtenue
For j = 1 To Len(Permutation)
Result + StringField(Groupe, Val(Mid(Permutation,j,1)), "~")+"~"
Next
;Afficher le résultat
Debug LSet(Result, Len(Result) - 1)
;Permutation suivante
i + 1
Until Permutation = Pattern
EndProcedure
;Donne les combinaison de ce groupe
GetCombination("25~158~75~200")
;la pattern calculé sera "1234"
;1 correspond à 25
;2 correspond à 158
;3 correspond à 75
;4 correspond à 200
;Lors d'une permutation de pattern, si on obtient "2413"
;alors nous aurons le résultat "158~200~25~75"
Ref :
http://forum.purebasic.com/english/view ... 42#p208106
Re: Permutation de groupes de caractères
Publié : lun. 22/févr./2016 20:27
par Shadow
Attention, ça ne fonctionne pas toujours !
Essai avec ceci par exemple: 5~16~20~29~62~75~136~167~175~219
Il ne faut pas être limité à X groupe.
Micoute a dis que il pourrais y avoir des millions de groupe.
Perso ça me parait tout de même plus qu'énorme, aucun ordi ne peut calculer ça ?
Re: Permutation de groupes de caractères
Publié : lun. 22/févr./2016 20:30
par Micoute
Merci pour toutes vos réponses, le problème c'est qu'on est limité à 10 dimensions, parce qu'à la ligne 25 on a Pattern + Str(i), donc jusqu'à 9 il n'y a qu'un caractère.
Re: Permutation de groupes de caractères
Publié : lun. 22/févr./2016 20:36
par falsam
Shadow a écrit :Attention, ça ne fonctionne pas toujours !
Essai avec ceci par exemple: 5~16~20~29~62~75~136~167~175~219
là c'est normal car chaque composant de la pattern est composé des chiffre 1 à 9.
Avec ton exemple on a 10 composants pour un groupe. Donc ça ne fonctionne pas.
Est ce que Micoute à des groupes avec plus de 9 composants ? A lui de le dire.
L'autre solution est de passer par les lettres de l'alphabet.