Python 数尾递归的幂

Python 数尾递归的幂,python,recursion,data-structures,tail-recursion,Python,Recursion,Data Structures,Tail Recursion,我试图使用运行时间为log(n)的尾部递归来计算num的幂。据我所知,使用power//2而不是power-1的区别在于减少了运行时间。因此,当我计算这个值时,我需要将旧值乘以另外两个和,而不是一个。我的代码在达到(2,6)的幂_之前一直工作 主要的问题是,你的尾部价值没有得到充分的乘以。假设power=9,power//2=4,power-power//2=5,您只需要将value*num^3相乘。如果这不合理,请告诉我 另外,如果power==1,则必须返回num,如果值为1 def po

我试图使用运行时间为log(n)的尾部递归来计算num的幂。据我所知,使用power//2而不是power-1的区别在于减少了运行时间。因此,当我计算这个值时,我需要将旧值乘以另外两个和,而不是一个。我的代码在达到(2,6)的幂_之前一直工作

主要的问题是,你的尾部价值没有得到充分的乘以。假设power=9,power//2=4,power-power//2=5,您只需要将value*num^3相乘。如果这不合理,请告诉我

另外,如果power==1,则必须返回num,如果值为1

def power_of(num,power,value = 1):
    print ("power_of({},{},{})".format(num,power,value)) # this was how I debugged it
    if power == 0:
        return 1

    elif power == 1:
        return num if value == 1 else value

    elif power % 2 != 0:
        for a in range(1, power - power // 2):
          value *= num
        return power_of(num, power // 2 , value)

    else:
        for a in range(1, power - power // 2):
          value *= num
        return power_of(num, power // 2 , value * num * num)
输出:

print(power_of(2,9))
power_of(2,9,1)
power_of(2,4,16)
power_of(2,2,128)
power_of(2,1,512)
512

好的,尾部递归,对。我对另一个答案感到抱歉。您的方法应该可以工作,只需做一些修改。对于evens,您希望将num替换为num*num,并将value保留为value。对于赔率,您需要将num替换为num*num,使value*num成为值,然后在除以幂之前减去1

def power_of(num,power, value = 1):

    if power == 0:
      return value

    if power == 1:
        return value * num

    elif power % 2 != 0:
        return power_of(num*num, (power - 1) // 2, value * num)

    else:
        return power_of(num*num, power // 2, value)

print(power_of(2,6))
我几乎是从这本书中抄袭过来的

看看它是如何工作的:

from hypothesis import given, strategies as st, settings, example

def power_of(num,power):
    if power == 0:
        return 1
    elif power == 1:
        return num
    elif power % 2 != 0:
        return num * power_of(num*num, power // 2)
    else:
        return power_of(num*num, power // 2)

@given(st.integers(min_value=0), st.integers(min_value=0))
@example(2, 6)
def test_power_of(i, j):
    assert power_of(i, j) == i**j

递归函数称为Tail recursive,如果recursive是递归函数中要执行的最后一条语句。在计算
x
达到
n(x^n)
幂的情况下,一个普通的递归函数可以存储堆栈中的所有值,直到它达到
n==1
n==0
(根据您的基本条件),而我们不希望使用所有这些状态/实例。所以我们能做的就是把最新的状态保存在一个变量中,并在到达基本情况时返回该变量

    int x = scanner.nextInt(); 
    int n = scanner.nextInt();
    int res = printPower(x, n);
    int resTail =  printPowerTail (x, n, x);   
    System.out.println(res);     
    System.out.println(resTail);

static int printPower (int x, int n) {
    if (n == 1) 
        return x;
    if (n == 0)
        return 1;
    return x * printPower(x, n - 1); // this call will store all the instances of n till n == 1
}
static int printPowerTail (int x, int n, int flag) {
    if (n == 1) 
        return flag;
    if (n == 0)
        return 1;
    return printPowerTail(x, n - 1, flag * x);
}

你的代码全错了。检查(2,1)的幂函数。当然wikipedia有一个更有效的方法,我希望他能从我留下的地方找到它。额外的'power==1'基本情况的目的是什么?这不是尾部递归为什么你的递归函数命名为
printX
,而它实际上是纯的?
    int x = scanner.nextInt(); 
    int n = scanner.nextInt();
    int res = printPower(x, n);
    int resTail =  printPowerTail (x, n, x);   
    System.out.println(res);     
    System.out.println(resTail);

static int printPower (int x, int n) {
    if (n == 1) 
        return x;
    if (n == 0)
        return 1;
    return x * printPower(x, n - 1); // this call will store all the instances of n till n == 1
}
static int printPowerTail (int x, int n, int flag) {
    if (n == 1) 
        return flag;
    if (n == 0)
        return 1;
    return printPowerTail(x, n - 1, flag * x);
}