Evil Science A whole load of stuff

20Jun/130

C# Combination Generator

This is a simple class that produces combinations of the provided string. It offers the following options:

  1. Unique - store only unique values.
  2. Mask - store combinations that match the provided pattern; an underscore represents a wildcard. Defaults to a length of underscores equal to the combination source string.
  3. CombinationLength - the length of the combination to be produced; defaults to the length of the combination source string.

The combinations are stored in a generic list called

The class is displayed below, and it's usage is simple.


           csCombinationGenerator c = new csCombinationGenerator();
            c.Get("12333678");

            foreach (string s in c.Combinations) //output the 40320 combinations
                Console.WriteLine (s);

Mask and combination usage is equally simple.


            csCombinationGenerator c = new csCombinationGenerator();
            c.Mask = "8___";
            c.CombinationLength = 4;
            c.Get("12333678");

            foreach (string s in c.Combinations) //output the 210 combinations
                Console.WriteLine (s);

Using the unique property.


            csCombinationGenerator c = new csCombinationGenerator();
            c.Unique = true;
            c.Get("12333678");

            foreach (string s in c.Combinations) //output the 6720 combinations
                Console.WriteLine (s);

Here is the class. Copy and paste into into a new class in visual studio.


//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;

  /// <summary>
    /// Class to produce combinations of the provided string. Offers options for specifying
    /// a mask, storing unique values and length of combination to be produced.
    /// </summary>
    class csCombinationGenerator
    {
        /// <summary>
        /// Combinations stored here
        /// </summary>
        public List<string> Combinations { get; set; }

        /// <summary>
        /// Store unique values only. If true, will slow down the generation.
        /// </summary>
        public bool Unique { get; set; }

        /// <summary>
        /// If specified, only match patterns that match.
        /// Mask specified by underscore for wildcard,
        /// </summary>
        public string Mask { get; set; }

        /// <summary>
        /// Length of the combination to be produced
        /// </summary>
        public int CombinationLength { get; set; }



        /// <summary>
        /// Produce combinations of the provided string to the provided length
        /// </summary>
        /// <param name="pString">String to produce combinations from</param>
        /// <param name="pLength">length of combination required</param>
        /// <remarks>Specifying unique only will slow the routine down</remarks>
        public void Get(string pString)
        {
            Combinations = new List<string>();

            if (CombinationLength == 0)
                CombinationLength = pString.Length;
            else if (CombinationLength > pString.Length)
                throw new Exception("Combination length is greater than string length");
            else if (CombinationLength < 0)
                throw new Exception("Combination length is negative number");

            if (Mask == "" | Mask == null)
                Mask = new string('_', pString.Length);
            else if (Mask.Length != CombinationLength)
                throw new Exception("Mask length is not equal to string length");

                    

            Combine(pString.ToCharArray(), "", 0);

        }


        /// <summary>
        /// Recursive routine to perform the combinations, pDepth is reduced
        /// for each recursion and when 0 is reached the string pComb is added
        /// to t
        /// </summary>
        /// <param name="arr">Char array of characters to combine</param>
        /// <param name="pComb">The combination being built</param>
        /// <param name="pDepth">Current depth of the routine</param>
        private void Combine(char[] arr, string pComb, int pCurrentPos)
        {
            if (pCurrentPos < CombinationLength)
            {

                for (int i = 0; i < arr.GetLength(0); i++)
                {

                    if (    //examine the mask
                            Mask.Substring(pComb.Length, 1) == "_"
                            | Mask.Substring(pComb.Length, 1) == arr[i].ToString()
                        )
                    {

                    Combine(
                                //when an array item is used, make a copy of the array, excluding
                                //that value, and pass into the function.
                                arr.Where((value, index) => index != i).ToArray()
                                , pComb + arr[i].ToString()
                                , pCurrentPos + 1
                            );
                    }
                }
            }
            else
                if (Unique)
                {
                    if (!Combinations.Contains(pComb))
                        Combinations.Add(pComb);
                }
                else
                    Combinations.Add(pComb);

        }
    }
Filed under: C# Leave a comment
Comments (0) Trackbacks (0)

No comments yet.


Leave a comment

No trackbacks yet.