使用原语运算符求 N 至 K 深度的阶乘

问题描述 投票:0回答:4

难以使用以下方法提出解决方案:

  1. 迭代/控制流和
  2. 积累。

不仅仅是一个解决方案,更希望有一个带有提示和解释的答案。

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
python while-loop factorial
4个回答
0
投票

因为您不需要解决方案,而是想知道代码失败的原因,所以我会给您一些指示

这里逻辑错误,这就是原因

  • 事实每次迭代都会更新,
  • 仔细检查 while 条件 i < k or i <= k?

0
投票

首先你需要生成数字来应用乘法

例如

# 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
投票

您正在谈论“下降阶乘”,也称为“下降幂”。它通常发音为“n 到 k 下降”。

整数参数

对于正整数参数,可以将其计算为阶乘之比:

n! / (n - k)!
。在 Python 中,这翻译为:

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]

-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 将从 0 开始递增 1,因此您只需从 n 中减去它即可得到下一个要乘以的数字。

编辑:通过提前返回来确保 k=0 始终返回 1

编辑2:删除内置范围功能

Edit3:确保深入

© www.soinside.com 2019 - 2024. All rights reserved.