C#如何打印相加到给定数字的组合?
我正试图用C#使用动态编程实现“将N表示为其他数字之和的不同方式的计数”问题。 我的方法如下所示:C#如何打印相加到给定数字的组合?,c#,recursion,dynamic,numbers,add,C#,Recursion,Dynamic,Numbers,Add,我正试图用C#使用动态编程实现“将N表示为其他数字之和的不同方式的计数”问题。 我的方法如下所示: static int howManyWays(int n) { int [] safe= new int[n + 1]; // base cases safe[0] = safe[1] = safe[2] = 1; safe[3] = 2; // iterate for all values
static int howManyWays(int n)
{
int [] safe= new int[n + 1];
// base cases
safe[0] = safe[1] = safe[2] = 1;
safe[3] = 2;
// iterate for all values from 4 to n
for (int i = 4; i <= n; i++)
safe[i] = safe[i - 1] + safe[i - 3]
+ safe[i - 4];
return safe[n];
}
我想打印出这4个总和的组合:
1+1+1+1
1+3
3+1
4
有什么方法可以递归地或使用动态编程来实现这一点吗?
我尝试递归地获得一组组合:
static int[] Combs(int n)
{
int[] tusc = { };
if (n < 0)
yield break;
if (n == 0)
yield return tusc;
int[] X = { 1, 3, 4 };
for(int i = 0; i < X.Length; i++)
{
for(j = 0; j <= Combs(n-X[i]).Length; j++)
{
yield return X + j;
}
}
}
静态int[]梳(int n)
{
int[]tusc={};
if(n<0)
屈服断裂;
如果(n==0)
收益率;
int[]X={1,3,4};
对于(int i=0;i 对于(j=0;j,这里有一个非常直接的翻译:
using System;
using System.Collections.Generic;
class MainClass
{
static IEnumerable<List<int>> Combs(int n)
{
if (n < 0)
{
yield break;
}
else if (n == 0)
{
yield return new List<int>();
}
foreach (int x in new List<int>() {1, 3, 4})
{
foreach (IEnumerable<int> combi in Combs(n - x))
{
var result = new List<int>() {x};
result.AddRange(combi);
yield return result;
}
}
}
public static void Main(string[] args)
{
foreach (IEnumerable<int> nums in Combs(5))
{
foreach (var i in nums)
{
Console.Write(i + ", ");
}
Console.WriteLine();
}
}
}
备注:
- 由于使用的是
yield
,请更改Combs
标题以返回IEnumerable
而不是int[]
- 使用列表而不是固定长度数组和
List.AddRange
从Python转换+
列表串联操作
- 在Python版本中,
X
只是{1,3,4}
选项列表中的一个元素,但在C版本中,它是整个数组
Combs(n-X[i]).Length
没有意义——它调用Combs
,获取结果的长度,然后丢弃所有结果,因此它就像一个非常昂贵的计数器。j
为您提供计数器索引,而不是子Combs
调用中的任何元素。foreach
是最准确的转换Python的for..in
循环
{1,3,4}
列表可能应该被设置为一个参数,以允许调用方控制其行为
- 效率很低,因为重叠的子问题被重新计算。改进它只是一个练习(无论如何,这可能是你的下一步)
def combis(n):
if n < 0:
return
if n == 0:
yield []
for x in (1, 3, 4):
for combi in combis(n-x):
yield [x] + combi
>>> list(combis(5))
[[1, 1, 1, 1, 1], [1, 1, 3], [1, 3, 1], [1, 4], [3, 1, 1], [4, 1]]
using System;
using System.Collections.Generic;
class MainClass
{
static IEnumerable<List<int>> Combs(int n)
{
if (n < 0)
{
yield break;
}
else if (n == 0)
{
yield return new List<int>();
}
foreach (int x in new List<int>() {1, 3, 4})
{
foreach (IEnumerable<int> combi in Combs(n - x))
{
var result = new List<int>() {x};
result.AddRange(combi);
yield return result;
}
}
}
public static void Main(string[] args)
{
foreach (IEnumerable<int> nums in Combs(5))
{
foreach (var i in nums)
{
Console.Write(i + ", ");
}
Console.WriteLine();
}
}
}
1, 1, 1, 1, 1,
1, 1, 3,
1, 3, 1,
1, 4,
3, 1, 1,
4, 1,