首页 新闻 搜索 专区 学院

有1,2,3,4,5 这几个数,他们之间相加得10的结果有哪些

0
[已解决问题] 解决于 2012-01-17 15:02

有1,2,3,4,5 这几个数,他们之间相加得10的结果有哪些。。
这题怎么做?用程序的话。

应该算是算法题了吧,我知道一共有2的5次方种排列方式,但是我不知道怎么用程序来表述这种排列方式,怎么循环出来?

问题补充:

也许给的示例太规律了。。。这样吧。。

假设有3,4,3,6,7,5,3这几个数,求用这几个数加起来等于9的结果,一个数只能用一次,这样结果就是

3+6=9

3+3+3=9

4+5=9

一楼的经测试可以,但是,我如果想计算小数呢?

假如数列是  double[] numbers = new double[] { 0.5, 0.1, 0.6, 0.3, 0.8, 0.06, 0.89, 0.02, 0.36 };

最后我想计算的结果是0.52,这样的话一楼的方法就行不通了。。晕。

牛腩的主页 牛腩 | 初学一级 | 园豆:-6
提问于:2012-01-17 12:32
< >
分享
最佳答案
0

这个不叫排列吧,加法满足交换律。我想的组合的算法, 这些被加数要么选中,要么不选中,放在一起,正好组成了1-2的n次方-1的数。全部没选中的不算, 然后只要把这些组合中相加结果为10的选出来就OK了, 哈哈,我的算法还是蛮好的:


            int[] numbers = new int[] { 1, 2, 3, 4, 5 };
int elementCount = numbers.Length;
int lastCombination = 2 << elementCount - 1;
int firstCombination = 1;
int sum;
const int targetSum = 10;

for (int i = firstCombination; i <= lastCombination; i++)
{
sum = 0;
for (int pos = 0; pos < elementCount; pos++)
{
if ((i & (1 << pos)) != 0) //当前组合第pos个数是否取中
sum += numbers[pos];
}
if (sum == targetSum)
{
for (int pos = 0; pos < elementCount; pos++)
if ((i & (1 << pos)) != 0)
Console.Write("{0}\t", numbers[pos]);
Console.WriteLine();
}
}
Console.ReadLine();


ChatinCode | 老鸟四级 |园豆:2272 | 2012-01-17 13:23
    static class SumFinder
{
public static void FindSum(dynamic numbers, dynamic targetSum)
{
int elementCount = numbers.Length;
int lastCombination = 2 << elementCount - 1;
int firstCombination = 1;
dynamic sum;
for (int i = firstCombination; i <= lastCombination; i++)
{
sum = 0;
for (int pos = 0; pos < elementCount; pos++)
{
if ((i & (1 << pos)) != 0) //当前组合第pos个数是否取中
sum += numbers[pos];
}
if (sum == targetSum)
{
for (int pos = 0; pos < elementCount; pos++)
if ((i & (1 << pos)) != 0)
Console.Write("{0}\t", numbers[pos]);
Console.WriteLine();
}
}
Console.ReadLine();
}
}
//调用方法
SumFinder.FindSum(new double[] { 0.5, 0.1, 0.6, 0.3, 0.8, 0.06, 0.89, 0.02, 0.36 }, 0.52);
SumFinder.FindSum(new int[] { 1, 2, 3, 4, 5 }, 10);

以上代码可在.net 4.0及以上运行

ChatinCode | 园豆:2272 (老鸟四级) | 2012-01-17 14:21

@ChatinCode: 这个可以正常运行了。可以得到最后的答案了。。呵呵。。如果可以的话加以解释一下就好了。。

&符号和<<符号好像是用于位运算位比较的吧。。呵呵。。做网站2年了都没有接触 过这些。。
牛腩 | 园豆:-6 (初学一级) | 2012-01-17 15:02

@牛腩: 最后这个代码少了些编译时的检查,因为使用了 dynamic。

ChatinCode | 园豆:2272 (老鸟四级) | 2012-01-17 15:07

@ChatinCode: 我自己已经改为可以在VS2008上运行了的。。呵呵。。得仔细看看为什么这样子得。。。主要是不知道位运算的意思。。。。

知道意思了也不知道为什么要那样子写。

牛腩 | 园豆:-6 (初学一级) | 2012-01-17 15:54

@牛腩: 难道这个算法看不懂,你把这些数排成一排,因为是组合问题,就是说这些数中要取到的数可以标记为1,未取到的可标为0。这样不就对应了0到2的n次方-1的二进制数(n为数的个数),这些组合中取0个数的显然不行。i & (1 << pos)是取 i 的第 pos位数(二进制)。<< 二进制左移 , & 二进制与。不知道够明白吗??

ChatinCode | 园豆:2272 (老鸟四级) | 2012-01-18 09:27
其他回答(2)
0

用递归。这段代码应该还可以再优化的。

        static void Main(string[] args)
{
var numbers = new []{ 1, 2, 3, 4, 5 };
int total = 10;
FindCombinations(numbers, total);

results.ForEach(r => Console.WriteLine(string.Join(",", r)));
Console.Read();
}

static List<int[]> results = new List<int[]>();
static Stack<int> currentResult = new Stack<int>();

static void FindCombinations(int[] numbers, int total)
{
if (numbers.Length == 0 && total == 0)
{
results.Add(currentResult.ToArray());
}
else
{
for (int i = 0; i < numbers.Length; i++)
{
var j = i;
currentResult.Push(numbers[j]);
FindCombinations(numbers.Skip(j + 1).ToArray(), total - numbers[j]);
currentResult.Pop();
}
}
}
水牛刀刀 | 园豆:6350 (大侠五级) | 2012-01-17 13:07
0

问题不明确,什么叫“他们之间相加得10的结果有哪些。。”,是第一和第二个相加,还是前几个相加?提问,问题得明确吧?是否是"斐波那契数列"?

根据你的问题,先决条件,有几个数是固定的还是变量,和是定数还是变量?如果以现在给出的条件,就循环遍历,把所有数据放进数组,用n+(N+1)=9的方式做吧,n表示数组索引。

lonely_rain | 园豆:752 (小虾三级) | 2012-01-17 13:16
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册