首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >生成3个和为n的数字

生成3个和为n的数字
EN

Stack Overflow用户
提问于 2015-07-10 17:37:58
回答 2查看 92关注 0票数 2

我需要生成三个自然数,它们的和是n。第一个数字可以是最大x,第二个数字可以是最大y,最后一个数字可以是最大z。目前我正在做这件事

代码语言:javascript
复制
def f(n):
    return [(i, j, k)
            for i in range(x+1)
            for j in range(y+1)
            for k in range(z+1)
            if i + j + k == n]

但是n很大,在500x, y, z附近都不到200。目前,我有3个变量(i, j, k)从3个范围生成。在列表理解中使用两个循环可以做到这一点吗?

EN

回答 2

Stack Overflow用户

发布于 2015-07-10 17:40:53

是啊,

您可以只计算第三个数字,并检查它是否在正确的范围内(Martijn♦)。

代码语言:javascript
复制
[(i, j, n - i - j) for i in range(x+1) for j in range(y+1) if 0 <= n - i - j <= z]
票数 3
EN

Stack Overflow用户

发布于 2015-07-10 17:52:56

您需要做的是根据第一个变量(j)的值约束第二个变量(i),并根据两个第一个变量约束最后一个变量(k):

代码语言:javascript
复制
l = []
for i in range(1, x + 1):
    for j in range(max(1, n - x - z), min(y + 1, n - x - 1)): # No need to go above n - x - 1or bellow n - x - z
        # For k, you do not even need a loop since it is constrained by i and j
        k = n - i - j 
        if 0 < k <= z:
            l.append((i, j, k))

我没有使用列表压缩来详细说明代码,但您当然可以:

代码语言:javascript
复制
[(i, j, n - i - j) for i in range(1, x + 1) for j in range(max(1, n - x - z), min(y + 1, n - x - 1)) if 0 < n - i - j <= z]

x等于1 (全局循环中的第一个值)时,y的范围从n - x - z = 500 - 1 - 200 = 299200,也就是说,您甚至不需要进入y循环,这是正常的,因为您需要x至少为100才能到达500 (因为<代码>D14和<代码>D15至多是<代码>D16)。

每次你面对这类问题时,想想“如何根据已经赋值的变量减少当前变量的域?”

顺便说一句,执行k = n - i - j赋值等同于对大小为01的范围进行循环,如下所示:

代码语言:javascript
复制
for k in range(max(1, n - i - j), min(z + 1, n - i - j + 1)):
    l.append((i, j, k))

请注意,在这种情况下,您不必再检查0 < k <= z

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31337478

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档