[Résolu] Permutation de groupes de caractères

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Micoute
Messages : 2584
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

[Résolu] Permutation de groupes de caractères

Message 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
Dernière modification par Micoute le lun. 22/févr./2016 20:57, modifié 1 fois.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Shadow
Messages : 1413
Inscription : mer. 04/nov./2015 17:39

Re: Permutation de groupes de caractères

Message 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
Processeur: Intel Core I7-4790 - 4 Cœurs - 8 Thread: 3.60 Ghz.
Ram: 32 GB.
Disque: C: SDD 250 GB, D: 3 TB.
Vidéo: NVIDIA GeForce GTX 960: 2 GB DDR5.
Écran: Asus VX248 24 Pouces: 1920 x 1080.
Système: Windows 7 64 Bits.

PureBasic: 5.60 x64 Bits.
Avatar de l’utilisateur
Micoute
Messages : 2584
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Permutation de groupes de caractères

Message par Micoute »

Oui, bien sûr, mais je ne sais pas comment le faire !
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Shadow
Messages : 1413
Inscription : mer. 04/nov./2015 17:39

Re: Permutation de groupes de caractères

Message 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 !
Processeur: Intel Core I7-4790 - 4 Cœurs - 8 Thread: 3.60 Ghz.
Ram: 32 GB.
Disque: C: SDD 250 GB, D: 3 TB.
Vidéo: NVIDIA GeForce GTX 960: 2 GB DDR5.
Écran: Asus VX248 24 Pouces: 1920 x 1080.
Système: Windows 7 64 Bits.

PureBasic: 5.60 x64 Bits.
Avatar de l’utilisateur
Micoute
Messages : 2584
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Permutation de groupes de caractères

Message 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 !
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Shadow
Messages : 1413
Inscription : mer. 04/nov./2015 17:39

Re: Permutation de groupes de caractères

Message par Shadow »

Ah ouais quand même :o
Processeur: Intel Core I7-4790 - 4 Cœurs - 8 Thread: 3.60 Ghz.
Ram: 32 GB.
Disque: C: SDD 250 GB, D: 3 TB.
Vidéo: NVIDIA GeForce GTX 960: 2 GB DDR5.
Écran: Asus VX248 24 Pouces: 1920 x 1080.
Système: Windows 7 64 Bits.

PureBasic: 5.60 x64 Bits.
Marc56
Messages : 2198
Inscription : sam. 08/févr./2014 15:19

Re: Permutation de groupes de caractères

Message 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 '~'

:wink:
Avatar de l’utilisateur
Micoute
Messages : 2584
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Permutation de groupes de caractères

Message 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.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
Micoute
Messages : 2584
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Permutation de groupes de caractères

Message 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
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Permutation de groupes de caractères

Message par Ar-S »

Le retour de la revanche de l'anagramme :mrgreen:
Et oui, même si ce sont des chiffres, c'est un anagramme que tu souhaites faire.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
cage
Messages : 604
Inscription : ven. 16/oct./2015 18:22
Localisation : France
Contact :

Re: Permutation de groupes de caractères

Message 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
■ Win10 Pro 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.12 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Permutation de groupes de caractères

Message 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
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Shadow
Messages : 1413
Inscription : mer. 04/nov./2015 17:39

Re: Permutation de groupes de caractères

Message 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 ?
Dernière modification par Shadow le lun. 22/févr./2016 20:31, modifié 1 fois.
Processeur: Intel Core I7-4790 - 4 Cœurs - 8 Thread: 3.60 Ghz.
Ram: 32 GB.
Disque: C: SDD 250 GB, D: 3 TB.
Vidéo: NVIDIA GeForce GTX 960: 2 GB DDR5.
Écran: Asus VX248 24 Pouces: 1920 x 1080.
Système: Windows 7 64 Bits.

PureBasic: 5.60 x64 Bits.
Avatar de l’utilisateur
Micoute
Messages : 2584
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Permutation de groupes de caractères

Message 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.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Permutation de groupes de caractères

Message 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.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Répondre