也许这不是最优雅的解决方案,因为我使用“不同”来过滤重复结果,但这是 C# 中的一种方法。
一般的想法是,您将数字拆分为一个 1 的数组,然后您只需像树一样将每个节点并排组合在一起,然后选择不同的组合。我是这样画的:
[1,1,1]
/ \
[2,1] [1,2]
\ /
[3]
class Program
{
static void Main(string[] args)
{
Console.Write("Enter an integer value: ");
int num = int.Parse(Console.ReadLine());
var y = new int[num];
for (int x = 0; x < num; x++)
y[x] = 1;
var results = Combine(y, num)
.Distinct(new ArrayComparer())
.OrderByDescending(r => r.Length)
.ToArray();
foreach (var result in results)
{
Console.Write('[');
for (int x = 0; x < result.Length; x++)
{
if (x > 0)
Console.Write(", ");
Console.Write(result[x]);
}
Console.WriteLine(']');
}
Console.ReadKey(true);
}
public class ArrayComparer : IEqualityComparer<int[]>
{
bool IEqualityComparer<int[]>.Equals(int[] x, int[] y)
{
if (x.Length == y.Length)
{
for (int z = 0; z < x.Length; z++)
if (x[z] != y[z])
return false;
return true;
}
return false;
}
int IEqualityComparer<int[]>.GetHashCode(int[] obj)
{
return 0;
}
}
public static IEnumerable<int[]> Combine(int[] values, int num)
{
int val = 0;
for (int x = 0; x < values.Length; x++)
val += values[x];
if (val == num)
{
yield return values;
if (values.Length - 1 > 0)
{
for (int x = 0; x < values.Length; x++)
{
int[] combined = new int[values.Length - 1];
for (int y = 0; y < x; y++)
combined[y] = values[x];
if (values.Length > x + 1)
combined[x] = values[x] + values[x + 1];
for (int y = x + 2; y < values.Length; y++)
combined[y - 1] = values[y];
foreach (var result in Combine(combined, num))
yield return result;
}
}
}
}
}
输出:
Enter an integer value: 4
[1, 1, 1, 1]
[2, 1, 1]
[1, 2, 1]
[1, 1, 2]
[3, 1]
[2, 2]
[1, 3]
[4]