C#找到所有可能的数字组合

C#找到所有可能的数字组合,c#,algorithm,permutation,C#,Algorithm,Permutation,我正在努力制作一种算法,将一组数字“洗牌”,使它们从0开始按升序排序,下一个数字不能超过前一个+1,它们的长度也必须为15,并且必须包括这组数字中的每一个数字。例如,如果我们有数字: 0,1 所需输出为: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1(是的,这些是14个零) 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 如果数字是一样的话 0,1,2 0,0,0,0,0,0,0,0,0,0,

我正在努力制作一种算法,将一组数字“洗牌”,使它们从0开始按升序排序,下一个数字不能超过前一个+1,它们的长度也必须为15,并且必须包括这组数字中的每一个数字。例如,如果我们有数字:

0,1

所需输出为:

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1(是的,这些是14个零)

0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1

0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

如果数字是一样的话

0,1,2

0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2(必须包括每个数字)

我尝试了以下方法,但失败惨重:

第1版

private static List<List<int>> GetNumbers(int lastNumber)
    {
        if (lastNumber == 0)
        {
            return new List<List<int>> { new List<int> { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
        }
        int[] setOfNumbers = new int[lastNumber + 1];
        List<List<int>> possibleRoutes = new List<List<int>>().ToList();
        for (int i = 0; i <= lastNumber; i++)
        {
            setOfNumbers[i] = i;
        }
        var temp = new List<int>();
        int[] possibleRoute = new int[15];
        for (int j = 0; j < size - lastNumber; j++)
        {
            possibleRoute[j] = 0;
        }
        for (int j = lastNumber; j < possibleRoute.Length; j++)
        {
            for (int k = j; k > 0; k--)
            {
                possibleRoute[k] = lastNumber - 1;
            }
            for (int i = size - 1; i >= j; i--)
            {
                possibleRoute[i] = lastNumber;
            }
            possibleRoutes.Add(possibleRoute.ToList());
            generalCounter++;
        }
        return possibleRoutes;
    }
private静态列表GetNumbers(int lastNumber)
{
如果(lastNumber==0)
{
返回新列表{newlist{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
}
int[]setOfNumbers=新int[lastNumber+1];
List possibleRoutes=新列表().ToList();
对于(int i=0;i 0;k--)
{
可能数[k]=lastNumber-1;
}
对于(int i=size-1;i>=j;i--)
{
possibleRoute[i]=最新编号;
}
Add(possibleRoute.ToList());
通用计数器++;
}
返回可能的输出;
}
第2版

private static List<List<int>> GetNumbers(int lastNumber)
    {
        if (lastNumber == 0)
        {
            return new List<List<int>> {new List<int> {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
        }
        int[] setOfNumbers = new int[lastNumber + 1];
        List<List<int>> possibleRoutes = new List<List<int>>().ToList();
        for (int i = 0; i <= lastNumber; i++)
        {
            setOfNumbers[i] = i;
        }
        var temp = new List<int>();
        int[] possibleRoute = new int[15];
        for (int j = 0; j < size - lastNumber; j++)
        {
            possibleRoute[j] = 0;
        }
        for (int i = 1 ; i <= lastNumber ; i++)
        {
            int newNumber = lastNumber - i;
            for (int k1 = i + 1; k1 <= size; k1++)
            {
                for (int j = possibleRoute.Length - 1; j > k1 - i - 1; j--)
                {
                    possibleRoute[j] = lastNumber;
                }
                for (int k = i; k <= k1 - 1; k++)
                {
                    possibleRoute[k] = newNumber;
                }
                possibleRoutes.Add(possibleRoute.ToList());
                generalCounter++;
            }
        }
        return possibleRoutes;
    }
private静态列表GetNumbers(int lastNumber)
{
如果(lastNumber==0)
{
返回新列表{newlist{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
}
int[]setOfNumbers=新int[lastNumber+1];
List possibleRoutes=新列表().ToList();

对于(inti=0;i我误解了这个问题。重新开始这个答案

让我们用另一种方式来陈述这个问题

我们有很多东西,十五件

我们有很多数字,比如0,1,2

我们想知道x零,y一和z二的组合是什么,这样x+y+z=15,x,y和z都至少是一

因此,将其简化为一个更简单的问题。假设有一个0。现在你能解决更简单的问题吗?现在问题更小了:问题是“生成长度为14且至少有一个1和一个2的所有序列”。你知道如何解决更简单的问题吗

如果没有,把它分解成一个更简单的问题。假设有一个1。你现在能解决这个问题吗?现在的问题是找到所有序列中有十三个2,并且只有其中一个

现在假设有两个1,你能解决这个问题吗


你知道如何使用简单问题的解决方案来解决更难的问题吗?

一个简单的策略,可以处理各种各样的问题,例如,按字典顺序列出各种可能性。在伪代码中,你可以这样做:

  • 按字典顺序将V设置为第一个可能的序列

  • 重复以下步骤:

    • 输出V
    • 如果可能,按字典顺序将V设置为下一个序列
    • 如果不可能,则退出循环
  • 在许多情况下,您可以通过在V中向后搜索最右边的“可递增”值来解决第二个子问题(“将V设置为下一个序列”);也就是说,可以递增的最右边的值会产生序列的可能前缀。一旦该值递增(以最小值递增),您可以找到以该前缀开头的最小序列。(这是第一个子问题“查找最小序列”的简单概括。)

    在这种情况下,这两个子问题都很简单

    • 如果某个值不是集合中的最大值且与前一个值相同,则该值可递增。该值只能递增到集合中下一个较大的值

    • 要查找以
      k
      结尾的前缀开头的最小序列,首先查找集合中大于
      k
      的所有值,并将它们按顺序排列在序列末尾。然后用
      k
      填充前缀后面的其余值(如果有)


    有关此方法在不同枚举问题上的应用,请参见。这也是
    next\u permutation

    标准实现的精髓。您可以演示您迄今为止所做的尝试吗?现在,您可以解释一下您遇到的具体问题吗?哪些不起作用?请记住,此网站上的人员我们是真正的人,在你不告诉我们的情况下很难猜出你在想什么。我们不会只是浏览一下你的代码,就能看出它有什么问题,也不会把它“带回我们的办公桌”然后花上几个小时试图找出如何让它工作。这个网站是关于具体的问题。代码完全被破坏了,有不止一个问题在那里,我真诚地期待着一个不同的方法,然后我的。我真的不想让人们使用我的代码,因为这太糟糕了,我还是初学者,我发布它只是为了向大家展示u我尽了我所能,但没能让它工作。据我所知,你建议我创建一个列表,列出所有当前已知的特定长度的解决方案,然后递归地添加更多内容。我可能完全错了,但即使我不是,我也不知道如何实现它。@KOPEUE:不要担心像列表这样的实现细节s在这一点上。你需要能够在几张纸上解决问题的小版本。写下所有长度为3的解决方案,例如从数字0、1、2中提取。它们不太多。现在,给出解决方案列表,描述如何将其转换为长度为4的解决方案列表。获得一些见解如何解决这个问题