C#找到所有可能的数字组合
我正在努力制作一种算法,将一组数字“洗牌”,使它们从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版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,
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的解决方案列表。获得一些见解如何解决这个问题