Combinaisons de caractères

Soyez le premier à donner votre avis sur cette source.

Snippet vu 8 356 fois - Téléchargée 18 fois

Contenu du snippet

Suite à une question sur le forum, voici ma solution pour trouver tous les arrangement de longueur fixe d'une liste de caractères.

Principe

Le principe est de définir une base de numération dont les caractères sont ceux de la chaine fournie en entrée.

On compte ensuite de 0 à n, ou n est le nombre de combinaisons - 1.

Ces combinaisons sont de longueur fixe et permettent les répétitions.


Arrangement.Arrange("ABC", 2) retournera:
AA
AB
AC
BA
BB
BC
CA
CB
CC

Source / Exemple :

 
using System; 
using System.Collections.Generic; 

namespace test 
{ 
     public static class Arrangement 
    { 
        /// <summary> 
        /// Retroune la liste de tous les arrangements de carractères 
        /// </summary> 
        /// <param name="caracteres">Chaine contenant les caractères à arranger</param> 
        /// <param name="longueur">Longueur des chaines attendues</param> 
        /// <returns></returns> 
        public static List<string> Arrange(string caracteres, int longueur) 
        { 
            List<string> liste = new List<string>(); 

            //calcul du nombre de permuation 
            int nbrePermut = (int)Math.Pow(caracteres.Length, longueur); 

            //boucle de comptage de 0 à nbrePermut 
            for (int i = 0; i < nbrePermut; i++) 
            { 
                string texte = string.Empty; 

                //conversion dans la base qui va bien 
                int[] valeurBase = Arrangement.BaseFromDecimal(i, caracteres.Length, longueur); 

                //association de chaque valeur de la base avec le caractère associé 
                for (int j = 0; j < longueur; j++) 
                    texte = caracteres[valeurBase[j]].ToString() + texte; 

                liste.Add(texte); 
            } 

            return liste; 
        } 

        /// <summary> 
        /// Retourne un tableau de int representant la conversion d'un entier décimal en une base quelquonque 
        /// </summary> 
        /// <param name="nDecimal">Decimal à convertir</param> 
        /// <param name="nBase">Base de conversion</param> 
        /// <param name="longueur">Longueur du mot en sortie (exemple 0 en 3 caractères 000)</param> 
        /// <returns></returns> 
        private static int[] BaseFromDecimal(int nDecimal, int nBase, int longueur) 
        { 
            int[] valeur = new int[longueur]; 
            int dividende = nDecimal; 

            for (int i = 0; i<longueur;i++) 
            { 
                if (dividende != 0) 
                { 
                    int reste; 
                    dividende = Math.DivRem(dividende, nBase, out reste);//on divise par la base et on garde le reste 
                    valeur[i] = reste;//le reste est affecté à la valeur en cours 
                } 
                else valeur[i] = 0; //rempli les vides 
            } 

            return valeur; 
        } 
    } 
} 



A voir également

Ajouter un commentaire

Commentaires

pgl10
Messages postés
310
Date d'inscription
samedi 18 décembre 2004
Statut
Membre
Dernière intervention
6 juillet 2019
1 -
Le nombre d'arrangements avec répétition de n éléments pris k à k est n^k ( n puissance k ). A mon avis, il s'agit ici des arrangements avec répétition de caracteres.Length caractères pris longueur à longueur et non pas de permutations.
Whismeril
Messages postés
13827
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
15 octobre 2019
309 -
Certes.

Correction apportée, j'ai laisse un permutation dans les mots clés, pour le cas ou d'autre fassent la même confusion que moi.
John-As
Messages postés
1
Date d'inscription
vendredi 20 janvier 2017
Statut
Membre
Dernière intervention
24 janvier 2017
> Whismeril
Messages postés
13827
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
15 octobre 2019
-
J'ai beaucoup apprécié ton raisonnement, je l'avais fait autrement

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
 class Program
 {
  static void Main(string[] args)
  {
   string s = "ABCD";
   int longueur = 3;
   int nmbDeVal = (int)Math.Pow(s.Length, longueur);
   string texte;
   int x;
   for (int i = 0; i < nmbDeVal; i++)
   {
    texte = "";
    for (int j = longueur - 1; j >= 0; j--)
    {
     x = i / (int)Math.Pow(s.Length,j) % s.Length;
     texte += s[x];
    }
    Console.Write(texte + "//");
   }
  }
 }
}
Whismeril
Messages postés
13827
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
15 octobre 2019
309 > John-As
Messages postés
1
Date d'inscription
vendredi 20 janvier 2017
Statut
Membre
Dernière intervention
24 janvier 2017
-
Bonsoir,

merci.

A l'époque j'ai préféré faire une méthode pour la conversion de base et une pour "compter" les permutations. L'avantage étant que la conversion de base peut être utilisée indépendamment.
Mais bien sûr ça peut être condensé comme tu l'as fait, et même un peu plus je pense avec Linq.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.