提问人:mks 提问时间:8/22/2020 最后编辑:martineaumks 更新时间:11/15/2023 访问量:1640
使用原始运算符查找 N 到 K 深度的阶乘
Using primitive operators to find factorial of N up to K depth
问:
使用以下方法难以提出解决方案:
- 迭代/控制流和
- 积累。
不仅仅是一个解决方案,更希望有一个带有提示和解释的答案。
def falling(n, k):
"""Compute the falling factorial of N to depth K.
>>> falling(6, 3) # 6 * 5 * 4
120
>>> falling(4, 3) # 4 * 3 * 2
24
>>> falling(4, 1) # 4
4
>>> falling(4, 0)
1
"""
fact = n
i = 0
while i <= k:
fact = fact * fact - 1
i += 1
n -= 1
return fact
答:
-1赞
Timbolt
8/22/2020
#1
def falling(n, k):
"""Compute the falling factorial of N to depth K.
>>> falling(6, 3) # 6 * 5 * 4
120
>>> falling(4, 3) # 4 * 3 * 2
24
>>> falling(4, 1) # 4
4
>>> falling(4, 0)
1
"""
if k == 0:
return 1
return_value = 1
counter = 0
while counter < k:
return_value = return_value * (n-counter)
counter += 1
return return_value
忽略 k=0,您想将 k 个数字相乘,从 n 开始,以 n-k 结尾。上面循环 k 次,由于 i 将从 1 开始递增 0,因此您可以简单地从 n 中减去它以获得下一个要乘以的数字。
编辑:确保 k=0 始终通过提前返回来返回 1
编辑2:删除内置范围功能
编辑3:确保深入 k
评论
0赞
mks
8/22/2020
这太棒了。需要注意的是,它使用的是内置函数范围。
0赞
Timbolt
8/22/2020
我是误解了您不想使用它,还是只是想了解有关该内置函数的更多信息?
0赞
mks
8/22/2020
Timbolt,我只想使用原始运算符和 if/while 循环。没有内置功能,如范围等。
0赞
Timbolt
8/22/2020
我改了,这是你想要的吗?我假设您不希望范围函数更好地理解计算?否则,它只会让它更混乱。
0赞
mks
8/22/2020
Timbolt,谢谢你的帮助。这个问题有点棘手;它要求你做一个阶乘,最多 K 次,而不是 K 次。因此,对于 N=6 和 K=3,它有效,因为 N - K = 3 是正确的,因为我们想要 6 到 5, 4 的阶乘。但是,N=4 和 K=1 呢?当 N - K 仍然是 3 时,我们最终会得到 4 * 3 * 2 = 12 - 这是我们不想要的。我们想要 1 个深度,即 4 * 1 = 4
0赞
hisokareddy
8/22/2020
#2
由于您不想要解决方案,而是想要代码失败的原因,因此 ILL 会为您提供一些指示
逻辑是错误的,这就是原因
- 事实在每次迭代中都在更新,
- 仔细检查 while 条件 i < k 还是 i <= k?
评论
0赞
mks
8/22/2020
指针 1) 是的,我想知道如何保存(累积)结果。指针 2) 下面的代码由 Timbolt 通过返回静态 1 解决了 k 为 0 的问题。正如你所注意到的,我的问题在这里。1)如果必须使用while循环,我如何累积总数?2) 或者每次迭代都用 n -1 做 for 循环 K 次?
0赞
hisokareddy
8/23/2020
为了保留该值,只需使用另一个变量,它看起来会是这样的 res = res * fact,之后你需要在每次迭代中将 fact 递减 1,所以 fact = fact - 1(将 res 初始化为 1 ),此外,您需要查看正好 k 次,所以它应该是 i < k 如果你的 k 是 0,你可以根据你的偏好在循环之前返回 0 或 1
0赞
Yusuf Adel
9/11/2022
#3
首先,您需要生成数字以应用乘法
例如,我们通过使用# 6 * 5 * 4
range(n, k, -1)
=> 例如,对于 (n, k) = (6, 3) 将是 [6, 5, 4]
然后用 .reduce
def falling(n, k):
return reduce(lambda x, y: x * y, list(range(n, k, -1)))
# more readable
```python
def falling(n, k):
from operator import mul
return reduce(mul, list(range(n, k, -1)))
lambda x, y: x * y
=> 只得到两个数字的乘积
在 Python 3.8+ 中
你会使用math.prod()
def factorial_with_depth(n, k):
"""Compute the falling factorial of n to depth k."""
from math import prod # python 3.8+
return prod(range(n, k, -1))
0赞
Joren
11/15/2023
#4
您说的是“下降阶乘”,也称为“下降功率”。它通常发音为“n to the k falling”。
整数参数
对于正整数参数,它可以计算为阶乘的比率:。在 Python 中,这转换为:n! / (n - k)!
import math
def falling(n: int, k: int) -> int:
assert k >= 0
return math.factorial(n) // math.factorial(n - k)
举例说明:
>>> [falling(6, k) for k in range(6)]
[1, 6, 30, 120, 360, 720]
或者,也可以通过将二项式系数 “n 选择 k” 乘以 来计算,即 。n!
math.comb(n, k) * math.factorial(k)
真实论据
如果您有实数参数,则可以使用 gamma 函数,它将阶乘扩展到实数域。由于浮点数可能会溢出,因此最好使用 gamma 函数的对数:
def falling_real(x: float, n: int | float) -> float:
return math.exp(math.lgamma(x + 1) - math.lgamma(x - n + 1))
例如:
>>> falling_real(math.e, math.pi)
2.7574468451854215
请注意,这可能会导致轻微的数值错误:
>>> [falling_real(6, k) for k in range(6)]
[1.0, 6.000000000000003, 30.000000000000057, 120.00000000000009, 360.0000000000007, 720.0000000000008]
评论
fact * fact - 1
(fact * fact) - 1