加起来为特定数字的整数组合

时间:2014-08-07 19:52:53

标签: math combinations

我需要一个程序,用于长度为5的字母“01234”的所有组合,其中数字加起来为4或更少。

实例 00013, 00031, 00101, 10120

但不是 11213,00341

问题:

  1. 如何计算加起来为X的字符串数?
  2. 如何生成加起来的所有字符串?
  3. 如何生成所有添加到数字< = X?
  4. 的字符串
  5. 这个概念在数学中被称为什么? 更新:
  6. 如何找到添加到总和X的数字(数字)子集?
  7. 任何程序语言或伪代码都可以。概念我的意思是找到将加起来给定总和的数字子集。所以,另外我想得到一个算法来找到这些子集。找到所有组合然后过滤掉匹配的组合很容易,但对于较大的字母(数字串)来说不是时间效率。

5 个答案:

答案 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