我需要一个程序,用于长度为5的字母“01234”的所有组合,其中数字加起来为4或更少。
实例 00013, 00031, 00101, 10120
但不是 11213,00341
问题:
任何程序语言或伪代码都可以。概念我的意思是找到将加起来给定总和的数字子集。所以,另外我想得到一个算法来找到这些子集。找到所有组合然后过滤掉匹配的组合很容易,但对于较大的字母(数字串)来说不是时间效率。
答案 0 :(得分:2)
假设你想要所有的组合(看起来更像你的问题的排列,因为你列出了00013和00031)总计4,我想首先你需要一个数字分区程序来将总和4分成几部分,通过添加零将每个分区的长度扩展为5,如下所示:
1, 1, 1, 1 -> 1, 1, 1, 1, 0
1, 1, 2 -> 1, 1, 2, 0, 0
1, 3 -> 1, 3, 0, 0, 0
2, 2 -> 2, 2, 0, 0, 0
4 -> 4, 0, 0, 0, 0
然后你可以对它们进行排列。因为数字中有许多重复项,所以排列总数不是很大,例如1,1,1,1,0只有5个排列,11110,11101,11011,10111,01111。
关于如何进行数字分区,你可以查看here,关于排列,因为我是C ++程序员,我会在STL库中使用next_permutation函数,或者查看here。
这种方法很通用,你可以处理没有深度循环的任何和的组合。
答案 1 :(得分:0)
这是一个快速而肮脏的问题。我相信你会找到让它更有效的方法。代码使用数组而不是字符串。
// Calculate sum of all digits
func numsum(a: [Int]) -> Int {
return reduce(a, 0, { $0 + $1 })
}
// Maximum number allowed
let maxnum = 4
// Number of digits
let arlen = 5
// Number we are looking for
let reqnum = 4
// Array that holds the combinations
var a = Array(count: arlen, repeatedValue: 0)
// Array where we keep all positive results
var b = [[Int]]()
// Function to go over all combinations and storing those that add up to the number we are looking for
// Called recursively for each level starting with 0
func addNum(level: Int = 0) {
if level == arlen {
return
}
a[level] = 0
while a[level] <= maxnum {
//println(a)
if numsum(a) == reqnum {
b.append(a)
}
else {
addNum(level: level + 1)
}
a[level] += 1
}
}
// Calling the function
addNum()
// Printing it out so that it looks like strings
for arr in b {
for n in arr {
print(n)
}
println()
}
答案 2 :(得分:0)
Python中的其他Q&amp; D解决方案
for a in range(5):
for b in range(5):
for c in range(5):
for d in range(5):
for e in range(5):
if a + b + c + d + e <= 4:
print a, b, c, d, e
您可以将<=
替换为==
,将print
替换为N+= 1
。
有70个&#34;重复安排&#34;给和4,和126,总和&lt; = 4。
答案 3 :(得分:0)
(作文)是一个很好的起点。允许零(它需要考虑排序)会变得复杂。
虽然零使其复杂化,但你可能不得不要求数学堆栈能够获得通用公式,因为组合学可能变得相当棘手。否则,其他答案就足够了。
答案 4 :(得分:0)
我认为递归代码简短明了。它以字典顺序输出组合,没有多余的工作。
procedure Combine(Digits, Sum, AMax: Integer; CurrentValue: string);
if Digits = 0 then
output(CurrentValue)
else
for i := 0 to Min(Sum, AMax) do
Combine(Digits - 1, Sum - i, AMax, CurrentValue + IntToStr(i));
//usage
Combine(4, 3, 3, '');
输出:
0000
0001
技术
0003
0010
0011
0012
0020
0021
0030
0100
0101
0102
0110
0111
0120
0200
0201
0210
0300
1000
1001
1002
1010
1011
1020
1100
1101
1110
1200
2000
2001年
2010
2100
3000