将数字字符串拆分为单位和双位数字的可能组合

时间:2014-08-19 10:06:52

标签: c# algorithm

我有一个数字字符串,我希望将其分成单位和双位数字的可能组合。

例如:分割字符串" 59145"我想要以下组合:

5 9 1 4 5
5 9 1 45
5 9 14 5
5 91 4 5
5 91 45
59 1 4 5
59 1 45
59 14 5

我目前的代码如下:

namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (var combination in SplitNumbers("59145"))
            {
                foreach (var number in combination)
                {
                    Console.Write(number + " ");
                }
                Console.WriteLine();
            }

            Console.Read();
        }

        static IEnumerable<List<string>> SplitNumbers(string input)
        {
            int numberCombinations = Fibonacci(input.Length + 1);

            List<string> combination;
            string temp;
            int count;

            for (int i = 0; i < numberCombinations; i++)
            {
                combination = new List<string>();
                temp = input;
                count = 0;

                while (temp.Length > 0)
                {
                    combination.Add(temp.Substring(0, combinations[input.Length][i][count]));
                    temp = temp.Remove(0, combinations[input.Length][i][count]);
                    count++;
                }
                yield return combination;
            }
        }

        public static int Fibonacci(int n)
        {
            int a = 0;
            int b = 1;

            for (int i = 0; i < n; i++)
            {
                int temp = a;
                a = b;
                b = temp + b;
            }
            return a;
        }

        static int[][][] combinations = new int[][][]
        {
            //0 numbers
            new int[][]
            {
                new int[]{0}
            },
            //1 number
            new int[][]
            {
                new int[]{1}
            },
            //2 numbers
            new int[][]
            {
                new int[]{1,1},
                new int[]{2}
            },
            //3 numbers
            new int[][]
            {
                new int[]{1,1,1},
                new int[]{1,2},
                new int[]{2,1}
            },
            //4 numbers
            new int[][]
            {
                new int[]{1,1,1,1},
                new int[]{1,1,2},
                new int[]{1,2,1},
                new int[]{2,1,1},
                new int[]{2,2}
            },
            //5 numbers
            new int[][]
            {
                new int[]{1,1,1,1,1},
                new int[]{1,1,1,2},
                new int[]{1,1,2,1},
                new int[]{1,2,1,1},
                new int[]{1,2,2},
                new int[]{2,1,1,1},
                new int[]{2,1,2},
                new int[]{2,2,1}
            }
        };
    }
}

我的问题是我必须对每种可能的组合进行硬编码。我确信有一些可能以编程方式解决这个问题,但目前我不知道如何做到这一点。

1 个答案:

答案 0 :(得分:3)

使用递归,就可以这样做:

static IEnumerable<List<string>> Split(string input)
{
    return Split(input, new List<string>());
}

static IEnumerable<List<string>> Split(string input, List<string> current)
{
    if (input.Length == 0)
    {
        yield return current;
    }

    if (input.Length >= 1)
    {
        var copy = current.ToList();
        copy.Add(input.Substring(0, 1));
        foreach (var r in Split(input.Substring(1), copy))
            yield return r;
    }

    if (input.Length >= 2)
    {
        var copy = current.ToList();
        copy.Add(input.Substring(0, 2));
        foreach (var r in Split(input.Substring(2), copy))
            yield return r;
    }
}

然后打印项目列表:

foreach (var r in Split("59145"))
    Console.WriteLine(string.Join(",", r));

这是working fiddle