编程练习题(4)- 递归(Recursive)

参考KhanAcademy

1. Each recursive call should be on a smaller instance of the same problem, that is, a smaller subproblem.

2. The recursive calls must eventually reach a base case, which is solved without further recursion.

 

1. 计算阶乘n!

Javascript:

var factorial = function(n) {
    // base case: 
    if(n===0) {
        return 1;
    }
    // recursive case:
    return(n*factorial(n-1));
}; 

println("The value of 0! is " + factorial(0) + ".");
println("The value of 5! is " + factorial(5) + ".");

 

Python3:

def factorial(n):
    #base case
    if n == 0:
        return 1
    #recursive case
    return (n*factorial(n-1))

print("The result of 5! is", factorial(5))

 

2. 回文串的判断

1. If the string is made of no letters or just one letter, then it is a palindrome.(如果字符串至多只有一个字符,那么这是一个回文串)
2. Otherwise, compare the first and last letters of the string.(否则[字符数大于1时],比较字符串的第一个字符和最后一个字符是否相等)
3. If the first and last letters differ, then the string is not a palindrome.(如果首尾字符不相同,则该字符串不是回文串)
4. Otherwise, the first and last letters are the same. Strip them from the string, and determine whether the string that remains is a palindrome.(首尾相同,则去头去尾,重复1-3的判断)

5. Take the answer for this smaller string and use it as the answer for the original string.(原字符串是否回文串,答案和在算法过程中其产生的子字符串是否回文串的答案相同)

 

Javascript:

// Returns the first character of the string str
var firstCharacter = function(str) {
    return str.slice(0, 1);
};

// Returns the last character of a string str
var lastCharacter = function(str) {
    return str.slice(-1);
};

// Returns the string that results from removing the first
//  and last characters from str
var middleCharacters = function(str) {
    return str.slice(1, -1);
};

var isPalindrome = function(str) {
    // base case #1
    if(str.length <2){
        return true;
    }
    // base case #2
    if(firstCharacter(str) !== lastCharacter(str)){
        return false;
    }
    // recursive case
    return(isPalindrome(middleCharacters(str)));
};

 

Python:

def isPalindrome(string):
    # base case #1
    if len(string) < 2:
        return True
    # base case #2
    if string[0] != string[-1]:
        return False
    # recursive case
    return isPalindrome(string[1:(len(string)-1)]) 

testStr = ['a']
testStr.append("hfeK")
testStr.append("HeyyeH")
for i in range(3):
    print("Is string [", testStr[i], "] Palindrome?\n")
    print(isPalindrome(testStr[i]))

 

3. 求$x$的幂级数$x^n$

1). The base case is when $n=0$, and x^0 = 1(基本的情况是$n = 0$也就是$x^n=1$时)
2). If $n$ is positive and even, recursively compute $y = x^{n/2}$, and then $x^n = y \cdot y$ . Notice that you can get away with making just one recursive call in this case, computing $x^{n/2}$ just once,  and then you multiply the result of this recursive call by itself.(如果$n$是偶数,那么可以只计算一次$x^{n/2},调用一次递归计算结果$)
3). If $n$ is positive and odd, recursively compute $x^{n-1}$, so that the exponent either is 0 or is positive and even. Then, $x^n = x^{n-1} \cdot x$(如果$n$是正的奇数,那么递归地计算$x^{n-1}$,这个指数要么是0要么成为正的偶数,则$x^n = x^{n-1} \cdot x$)
4). If $n$ is negative, recursively compute $x^{-n}$, so that the exponent becomes positive. Then,$x^n = 1 / x^{-n}$.(如果$n$是负数,那么递归计算$x^{-n}$,则此时指数为正数)

Javascript:

var isEven = function(n) {
    return n % 2 === 0;
};

var isOdd = function(n) {
    return !isEven(n);
};

var power = function(x, n) {
    println("Computing " + x + " raised to power " + n + ".");
    // base case
    if(n===0){
        return 1;
    }
    // recursive case: n is negative 
    if(n<0){
        return 1/(power(x, -n));
    }
    // recursive case: n is odd
    if(isOdd(n)){
        return x*power(x, n-1);
    }
    // recursive case: n is even
    if(isEven(n)){
        var temp = power(x, n/2);
        return temp*temp;
    }
};

var displayPower = function(x, n) {
    println(x + " to the " + n + " is " + power(x, n));
};

displayPower(3, 0);
Program.assertEqual(power(3, 0), 1);

 

Python:

def power(x, n):
    # base case
    if n==0:
        return 1
    # recursive case: n is negative 
    if n<0:
        return 1/(power(x, -n))
    # recursive case: n is odd
    if n%2 != 0:
        return x*power(x, n-1)
    # recursive case: n is even
    if n%2 == 0:
        temp = power(x, n/2)
        return temp*temp

x=4
for i in range(5):
    print(x, "to the power", i, "is", power(x, i))

 

4. 利用递归画画:

Javascript:

var drawShape = function(x, y, radius) {
    
    fill(200, 100+radius/6, 100+radius/6);
    ellipse(x, y, radius, radius);
    //add some leaves
    for(var i = 0; i < 10; i++){
        var area = random(0, radius/4);
        image(getImage("avatars/leaf-green"),
        random(0, x+radius/2), random(0, y+radius/2), area, area);
    }
    //add the circles upside, leftside, rightside and downside
    ellipse(x, y-radius/4, radius/2, radius/2);
    ellipse(x, y+radius/4, radius/2, radius/2);
    ellipse(x+radius/4, y, radius/2, radius/2);
    ellipse(x-radius/4, y, radius/2, radius/2);
    var newRadius = radius/2;
    //recursively call the draw function
    if (newRadius >= 2) {
        //rotate(10);
        drawShape(x, y, newRadius);
    }

};

drawShape(width/2, height/2, 380);

效果如下(想让叶子换下角度,圆也是,但是加上rotate之后图就乱了,暂时没有去琢磨):

 

5.汉诺塔:

说明:

把A柱子的圆盘,按原来的顺序摆放到B柱子上:

在这个过程中要遵守两个规则:

1. 每次只能移动一个盘子;

2. 大的盘子不能放在小盘子的下面。

 

如果只有一个盘子,那么直接移动就可以了;

如果有1、2两个盘子,那么可以先把盘子1放到C -> 把盘子2放到B -> 把盘子1放到B,完成。

而对于更多的盘子:1,2,...,n,则先递归地把盘子们1-(n-1)放到C -> 把盘子n放到B -> 递归地把盘子们1-(n-1)放到B。

 

假设移动k个盘子需要$a_k$步,则移动(k+1)个盘子需要$a_k + 1 + a_k = 2*a_k +1$步。则$a_{k+1} = 2*a_k +1$,从而$(a_{k+1}+1) = 2*(a_k +1)$

而$a_1 = 1$

则$a_k +1= 2^k$,$a_k = 2^k -1$

 

Javacript:

 这里只给出一个框架,具体的移动时表现的内容没有加进来。

var solveHanoi = function(numDisks, fromPeg, toPeg) {
    // base case:  no disks to move
    if(numDisks === 0){
        return 0;
    }
    // recursive case:
    var sparePeg = hanoi.getSparePeg(fromPeg, toPeg);
    solveHanoi(numDisks-1, fromPeg, sparePeg);
    hanoi.moveDisk(fromPeg, toPeg);
    solveHanoi(numDisks-1, sparePeg, toPeg);
};

 

Python:

def move(fromPeg, toPeg):
    print(fromPeg, "->", toPeg, "\n")
    
def HanoiMove(numDisks, fromPeg, toPeg):
    sparePeg = ['A', 'B', 'C']
    # define the spare peg
    sparePeg.remove(fromPeg)
    sparePeg.remove(toPeg)
    # the base case: no disk to move
    if numDisks == 0:
        return 0
    # recursive case
    HanoiMove(numDisks-1, fromPeg, sparePeg[0])
    move(fromPeg, toPeg)
    HanoiMove(numDisks-1, sparePeg[0], toPeg)

HanoiMove(3, 'A', 'B')

打印结果如下:

A -> B 

A -> C 

B -> C 

A -> B 

C -> A 

C -> B 

A -> B

 

转载于:https://www.cnblogs.com/RRRRecord/p/7910224.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值