如何正确编写递归函数?

时间:2017-04-07 15:45:27

标签: python

我是Python新手,因此如果问题是基本的话,请道歉:

我想写一个函数来计算所需的最低月付款,以便在12个月内使用递归偿还信用卡余额。

鉴于以下内容:

initialBalance = 1000 # Thats my initial balance on card / debt
annualInterest = .2
startPeriod = 1 # when I start to begin my pament
minMonthPayment = 5 # I begin a monthly payment of 5 $

def repayment(initialBalance,annualInterest,minMonthPayment,startPeriod):

    while startPeriod < 12 and initialBalance > 0:
        monthRate = annualInterest/12
        interest = monthRate * initialBalance
        initialBalance -= minMonthPayment
        initialBalance += interest
        startPeriod += 1
        # Here I check if I still havent paid off the balance with initial 5 dollars
        # If not then I would like to call the function again and increase the minMonthPayment 
    if initialBalance > 0:
        repayment(initialBalance,
                  annualInterest,
                  minMonthPayment + 5,
                  startPeriod)
    return round(initialBalance,1)

print(repayment(1000,.2,5,1))  

然而,似乎没有适当地调用该函数并返回:

RecursionError: maximum recursion depth exceeded in comparison

3 个答案:

答案 0 :(得分:1)

您没有重置startPeriod变量。

第一次执行该功能时,这就是状态

def repayment(initialBalance,annualInterest,minMonthPayment,startPeriod):

    while startPeriod < 12 and initialBalance > 0:
        monthRate = annualInterest/12
        interest = monthRate * initialBalance
        initialBalance -= monthlyPayment
        initialBalance += interest
        startPeriod += 1

    #1st call of repayment: startPeriod is now 12 and initialBalance is 
    #greater than 0

    if initialBalance > 0:
        repayment(initialBalance,
                  annualInterest,
                  minMonthPayment,
                  startPeriod + 5) #start period becomes 17 here
    return round(initialBalance,1)

第二次执行该功能时,这就是状态

def repayment(initialBalance,annualInterest,minMonthPayment,startPeriod):

    #2nd call of repayment: startPeriod is now 17 so this loop is never 
    #run and your initialBalance will not be decreased
    while startPeriod < 12 and initialBalance > 0:
        monthRate = annualInterest/12
        interest = monthRate * initialBalance
        initialBalance -= monthlyPayment
        initialBalance += interest
        startPeriod += 1

    #initialBalance is still greater than zero in the 2nd call of 
    #repayment since the while loop wasn't run. You have created an 
    #infinataly recursive function
    if initialBalance > 0:
        repayment(initialBalance,
                  annualInterest,
                  minMonthPayment,
                  startPeriod + 5)
    return round(initialBalance,1)

答案 1 :(得分:0)

编码递归函数时,必须首先回答问题,此函数何时停止深入并实际返回值。此检查通常是递归函数的前几行。

首先你应该检查函数是否应该停止,如果它不需要停止,也就是说,如果它应该更深,你必须改变你传递的参数,以确保它最终满足这个条件。

例如,打印列表中所有元素的简单递归函数如下所示:

def print_list_recursive(list):
    # This is the condition that answers the question 'do we need to go deeper?'
    if list is empty: # DON'T GO DEEPER
        return
    else: # We have to go deeper
        first_element = remove_first_element(list)
        print first_element
        print_list_recursive(list) # list parameter is changed

注意每次深入时参数list如何变化。每次删除一个元素,最终列表将为空,我们将返回(停止深入)。

一旦您以递归方式定义问题并定义停止条件,递归似乎非常简单。

在“打印列表”问题中,您应该看到要打印列表,您只需打印第一个元素,然后在列表的其余部分调用print_list,再次打印第一个元素,然后在其余部分调用print_list。清单......所以我们什么时候停止?当我们到达停止条件时,即列表为空时。

在编码任何递归函数时,您可以应用相同的逻辑。

我希望这会有所帮助。

答案 2 :(得分:-1)

我对Python不熟悉,但是在这里我做了你在Java中提出的问题,也许你可以比较并将它应用到Python(我将尝试在一个在线python编译器上创建一个)

import java.lang.Math; // headers MUST be above the first class

public class PaymentCalculator
{
public static void main(String[] args)
{

System.out.print(repayment(1000,2,25,1));
}

static int repayment(int initialBalance, int annualInterest, int minMonthPayment, int startPeriod){

int monthRate = annualInterest / 12;
int interest = monthRate * initialBalance;


  for(int i =0; i < 12; i++){
    initialBalance -= minMonthPayment;
    initialBalance += interest;
    startPeriod++;

  }

if(initialBalance == 0 || initialBalance < 0){
  return minMonthPayment;
}
else
{
 return repayment(1000,2,minMonthPayment+25,1);
}        


}
}