Re: [Résolu] Permutation de groupes de caractères
Publié : lun. 29/févr./2016 21:02
Forums PureBasic - Français
http://forums.purebasic.com/french/
Code : Tout sélectionner
;Désactiver le support unicode dans les options de compilation
Global CountGroup, Result.s
;Split() permet de diviser une chaîne de caractères à partir d'un séparateur pour fournir un tableau de sous-chaînes.
;Cette fonctionnalité existe en JavaScript.
Procedure Split(Array Array.s(1), String.s, Delimiter.s)
Protected File, i, j, Buffer.s
j = CountString(String, Delimiter)
ReDim Array(j)
For i=1 To j+1
Array(i-1) = StringField(String, i, Delimiter)
Next
EndProcedure
;De quoi calculer le nombre de permutations possibles
Procedure.q Factoriel(n.q)
If n=0
ProcedureReturn #True
Else
ProcedureReturn n*Factoriel(n-1)
EndIf
EndProcedure
;Générer une permutation
Procedure.s SetPermutation(Pattern.s, n)
Protected i, Factorial = 1, Temp
For i = 2 To Len(Pattern)
Factorial * (i - 1)
*n1.Byte = @Pattern + (i - ((n / Factorial) % i) - 1)
*n2.Byte = @Pattern + i - 1
Temp = *n1\b
*n1\b = *n2\b
*n2\b = Temp
Next
ProcedureReturn Pattern
EndProcedure
;Combien de permutations possibles pour la combinaison passée en paramétre
Procedure GetPermutation(Combination.s, Delimitator.s)
Protected i,j
Protected Pattern.s ;Composer d'une séquence de chiffres (Exemple : ABCD)
Protected Permutation.s ;Permutation retournée par la procédure SetPermutation. Exemple (BDAC)
Protected Dim Combination.s(0) ;Trie du paramétre Combination
Protected MemCombination.s ;Mémorise le paramétre Combination passé en paramétre
Protected MemPattern.s ;Mémorise la pattern de travail correspondant à Combination
;0 - Affiche le nombre de combinaisons possibles pour la combinaison passée en paramétre.
Debug "La combinaison " + Combination + " est extraite de " + Factoriel(CountString(Combination, Delimitator) + 1) + " combinaisons possibles." + #CRLF$
;1 - Mémorisation de la combinaison passé en paramétre
MemCombination = Combination
;2 - Tri de la combinaison à l'aide d'un tableau
Split(Combination(), Combination, ".")
SortArray(Combination(), #PB_Sort_Ascending | #PB_Sort_NoCase)
Combination = ""
For i = 0 To ArraySize(Combination())
Combination + Combination(i) + "."
Next
Combination = LSet(Combination, Len(Combination) -1)
;La combinaison "Cube.Plane.Sphere.Cylinder" aprés tri est égale à "Cube.Cylindern.Plane.Sphere"
;3 - Création d'un pattern de travail : "Cube.Cylindern.Plane.Sphere" sera égale à A.B.C.D
For i = 1 To CountString(Combination, Delimitator) + 1
Pattern + Chr(64 + i) ;La lettre A commence à 65
Next
;4 - La combinaison mémorisée est à sont tour transformée en pattern de travail
For i = 1 To CountString(MemCombination, Delimitator) + 1
For j = 0 To ArraySize(Combination())
If Combination(j) = StringField(MemCombination, i, Delimitator)
MemPattern + Chr(64 + j+1)
EndIf
Next
Next
;5 - Recherche du nombre de permutation pour arriver à la combinaison "Cube.Plane.Sphere.Cylinder"
i=1
Repeat
Permutation = SetPermutation(Pattern, i)
If Permutation = MemPattern
Debug "Il a fallu " + i + " permutations pour arriver à la combinaison " + MemCombination
Break
EndIf
;Permutation suivante
i + 1
Until Permutation = Pattern
CountGroup = i
EndProcedure
;Combien de permutations il a fallut pour trouver "Cube.Plane.Sphere.Cylinder"
GetPermutation("Cube.Plane.Sphere.Cylinder", ".")
A noter que mon code est celui ci exactement (sans bug) :Spock a écrit :@SPH , il y a un truc qui déconne dans ton mélange
il arrive souvent qu'il y ai plusieurs fois le meme chiffre dans la variable A$Code : Tout sélectionner
a$="" For i=0 To 9 Swap p(i),p(Random(9)) a$+Str(p(i)) Next Debug a$
Code : Tout sélectionner
Dim p(9)
For i=0 To 9
p(i)=i
Next
For i=0 To 9
Swap p(i),p(Random(9))
Next
a$=""
For u=0 To 9
a$+Str(p(u))
Next
Debug a$
Ne dis pas non.Spock a écrit :non !SPH a écrit : Maintenant, ce que tu cherches est le nombre minimum d'echanges pour arriver a un arrangement precis.
Par exemple : 1,2,3,4 deviens 2,3,1,4
Et bien, le nombre d'echange est compris entre 1 et N-1
Par exemple, pour 4 elements (1,2,3,4), il faut entre 1 et 3 echanges seulement !
Exemple :
depart : 1,2,3,4
un echange : 2,1,3,4
un deuxieme echange : 2,3,1,4
fini
Code : Tout sélectionner
Dim p(9)
For i=0 To 9
p(i)=i
Next
For i=0 To 9
Swap p(i),p(Random(9))
Next
pass=0
a$=""
For u=0 To 9
a$+Str(p(u))
Next
Debug a$
Repeat
For i=0 To 9
If p(i)<>i
Swap p(i),p(p(i))
EndIf
b$=""
ok=0
For u=0 To 9
b$+Str(p(u))
If p(u)=u
ok+1
EndIf
Next
If a$<>b$
Debug b$
pass+1
a$=b$
EndIf
If ok=10
Goto fin
EndIf
Next
Until ok=10
fin:
Debug("Pass = "+Str(pass))
Quel algorythme en dehorss du mien ??Spock a écrit :
lorsqure tu me cites, ne sort pas du contexte ma citation en n'en prenant qu'une partie !
j'ai dit :et ça c'est une realité !non ! car tout depends de l'algorythme utilisé !![]()
Tu es bete ou quoi ?Spock a écrit :j'avais aussi ecris
et ça aussi c'est une realité !
non ! car tout depends de l'algorythme utilisé !
car si la methode d'echange est de type :
1,2,3,4
1,2,4,3
1,3,2,4
1,3,4,2
2,1,3,4
2,1,4,3
2,3,1,4
il faudra 7 echanges et pas 3 ....
tout depends de l'algo de permutation employé !
bref,sans cette donnée , c'est simplement impossible de prévoir le nombre de permutation qu'il faudra pour arriver au résultat final !
Quoi ? Que tu n'as pas su faire le moindre morceau de code pour me surpasser ?Spock a écrit :quelqu'un lui explique ?
Code : Tout sélectionner
nb=25
Dim p(nb)
For i=0 To nb
p(i)=i
Next
For i=0 To nb
Swap p(i),p(Random(nb))
Next
pass=0
a$=""
For u=0 To nb
a$+Chr(p(u)+65)
Next
Debug a$
Repeat
For i=0 To nb
If p(i)<>i
Swap p(i),p(p(i))
EndIf
b$=""
ok=0
For u=0 To nb
b$+Chr(p(u)+65)
If p(u)=u
ok+1
EndIf
Next
If a$<>b$
Debug b$
pass+1
a$=b$
EndIf
If ok=nb+1
Goto fin
EndIf
Next
Until ok=nb+1
fin:
Debug("Pass = "+Str(pass))
DUINMBSJCZLKOPQYVXREFTHGWA
NUIDMBSJCZLKOPQYVXREFTHGWA
NFIDMBSJCZLKOPQYVXREUTHGWA
NFCDMBSJIZLKOPQYVXREUTHGWA
NFCDOBSJIZLKMPQYVXREUTHGWA
NBCDOFSJIZLKMPQYVXREUTHGWA
NBCDOFRJIZLKMPQYVXSEUTHGWA
NBCDOFRZIJLKMPQYVXSEUTHGWA
NBCDOFRZIJKLMPQYVXSEUTHGWA
NBCDOFRZIJKLMYQPVXSEUTHGWA
NBCDOFRZIJKLMYVPQXSEUTHGWA
NBCDOFRZIJKLMYVPQGSEUTHXWA
NBCDEFRZIJKLMYVPQGSOUTHXWA
NBCDEFRZIJKLMYVPQGSTUOHXWA
NBCDEFRHIJKLMYVPQGSTUOZXWA
NBCDEFRHIJKLMYVPQGSTUOWXZA
ABCDEFRHIJKLMYVPQGSTUOWXZN
ABCDEFGHIJKLMYVPQRSTUOWXZN
ABCDEFGHIJKLMZVPQRSTUOWXYN
ABCDEFGHIJKLMZOPQRSTUVWXYN
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Pass = 20
Quel algo ? Il n'a rien ponduAr-S a écrit :@Dobro : SPH te dit que son algo met 23 pass à trouver le bon résultat, le tient en met (logiquement) 26
Il n'y a que 2 FOR dans ma boucle principale ! C'est ultra correcteAr-S a écrit :@SPH : Ok ton algo met moins de 26 pass, mais as tu vu le nombre de boucle For Next de ton code ?