1. 程式人生 > >一些利用遞迴思想的簡單程式設計題(JS實現)

一些利用遞迴思想的簡單程式設計題(JS實現)

1. 使用遞迴函式計算1+2+...100的值。

2. 定義函式,宰相的麥子:相傳古印度宰相達依爾,是國際象棋的發明者。
   有一次,國王因為他的貢獻要獎勵他,問他想要什麼。
   達依爾說:“只要在國際象棋棋盤上(共64格)擺上這麼些麥子就行了:
   第一格一粒,第二格兩粒,……,後面一格的麥子總是前一格麥子數的兩倍,
   擺滿整個棋盤,我就感恩不盡了。”國王一想,這還不容易,剛想答應,
   如果你這時在國王旁邊站著,你會不會勸國王別答應,為什麼?

3. 定義函式: 計算斐波那契數列第n項.   1 1 2 3 5 8 13...
    提示:傳入10, 就計算第10項

4. 定義函式, 根據傳入的年月日, 返回這個年月日是那一年的第幾天.

1.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>遞迴函式計算累加值</title>
</head>
<body>
<!--使用遞迴函式計算1+2+...100的值。-->
<script>
    var m=+prompt("請輸入需要計算的數:");
    function recursionSum(n) {
        if(n==1) return 1;
        return n+recursionSum(n-1);
    }

    document.write("結果是:"+recursionSum(m));

</script>
</body>
</html>

2.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Wheat of King</title>
</head>
<body>
<!--題目:定義函式,宰相的麥子:相傳古印度宰相達依爾,是國際象棋的發明者。
   有一次,國王因為他的貢獻要獎勵他,問他想要什麼。
   達依爾說:“只要在國際象棋棋盤上(共64格)擺上這麼些麥子就行了:
   第一格一粒,第二格兩粒,……,後面一格的麥子總是前一格麥子數的兩倍,
   擺滿整個棋盤,我就感恩不盡了。”國王一想,這還不容易,剛想答應,
   如果你這時在國王旁邊站著,你會不會勸國王別答應,為什麼?-->

<!--其次,我們考慮這個問題去用遞迴怎麼寫?首先遞迴的演算法一定可以通過迴圈結構語句去實現
    這一點必須明確,而且有時候遞迴演算法還算比較難維護的,但遞迴比較美觀啊。關鍵一點,需要讀者
    明白,遞迴每次遞迴呼叫都擁有自己的變數集合,所以就需要佔用較多的記憶體;
    每次遞迴呼叫需要把新的變數集合儲存在堆疊中。棧是一個後進先出(LIFO)的壓入(push)
    和彈出(pop)式的資料結構。
-->
<!--這裡存在一個精度問題:IEEE 754 規定,有效數字第一位預設總是1,不儲存在64位浮點數之中。
    也就是說,有效數字總是1.xx...xx的形式,其中xx..xx的部分儲存在64位浮點數之中,
    最長可能為52位。因此,JavaScript 提供的有效數字最長為53個二進位制位。
    精度最多隻能到53個二進位制位,這意味著,絕對值小於253次方的整數,
-(2^53-1)2^53-1,都可以精確表示。
-->
 <!--最後,寫遞迴,就是要列出其遞迴定義:F(1)=1,F(2)=2, F(n)=F(n-1)*2 (n > 1)--><script> /** * 遞迴函式 * @type {number} 麥子數 */ var m=+prompt("請輸入棋牌格子數:") function wheat(m) { if(m == 1){ return 1; } else if(m == 2){ return 2; } else if(m > 2){ return wheat(m-1)*2; } }//輸出其資訊 var sum=0; for(i=1;i<=m;i++){ document.write("第 "+i+" 個棋牌格子需要放: "+wheat(i)+"<br>"); sum+=wheat(i); } document.write(m+"個棋牌格子需要放: "+sum+" 顆麥子。")</script></body></html>

3.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Fibonacci數列</title>
</head>
<body>
<!--定義函式: 計算斐波那契數列第n項.   1 1 2 3 5 8 13...
    提示:傳入10, 就計算第10項
-->
<!--這是一個遞迴演算法,在遞迴過程檢驗中,我們可以利用遞迴樹的形式去理解遞迴,
    一層一層往下走當走到“值”時又一層一層往上面走,有點類似於圖的遍歷操作。
    或者他就是一個波峰,有上波峰和下波峰兩個process。
    如果 n 比較大的情況下還是推薦使用迭代。
-->
<script>
    var m=+prompt("請輸入斐波那契數列的項數:");
    document.write(Fibonacci(m));

    function Fibonacci(n) {
        if(n==1) return 1;
        if(n==2) return 1;
        return Fibonacci(n-1)+Fibonacci(n-2);
    }

</script>

</body>
</html>

4.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>輸出日期是一年的第幾天</title>
</head>
<body>

<script>
    //彈出年、月、日輸入框,讓user輸入並獲取
    var year = +prompt("請輸入年份:");
    var month = +prompt("請輸入月份:");
    var day = +prompt("請輸入日期:");

    //月
    //求各月份數字之和,核心之處:初始化2月份為28天,在後面判斷閏年平年再對總數進行增改;
    var getMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30);
    var sum = 0;
    for (var i = 0; i < month - 1; i++) {
        sum += getMonth[i]
    }

    //年
    //在這裡判斷是否閏年平年,是閏年且month大於2,那麼就天數加1;
    //注意,這裡是month大於2(從3月開始),不是大於等於2.這裡容易寫糊塗掉。

    var total;
    if ((year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) && month > 2) {
        total = sum + day + 1 ;
        document.write("該天為一年中的第" + total + "天");
    } else {
        total = sum + day ;
        document.write("該天為一年中的第" + total + "天");
    }
</script>
</body>
</html>

另解4:用遞迴思想

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>

function isLeap(year){
    return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
}
function isLegal(year, month, day){
    // 把一些明顯不合法的先攔截掉
    if (month > 12 || month < 1 || day > 31 || day < 1) return false;
    // day [1,31]
    if (month == 4 || month == 6 || month == 9 || month == 11){
        return day <= 30;
    }else if (month == 2){
        if (isLeap(year)){
            return day <= 29;
        }else{
            return day <= 28;
        }
    }
    return true;
}

function dayPerYear(year, month, day){ // 2018, 3, 30
    if(!isLegal(year, month, day)) return -1;
    if(month == 1) return day;
    return day + sumDays(year, month - 1) // 2018, 2
}
// 求前 month個月的總天數
function sumDays(year, month){  // 2018, 5
    if(month == 1) return 31;
    return sumDays(year, month - 1) + days(year, month);
}
// 求第month個月的天數
function days(year, month){
    if(month == 9 || month == 4 || month == 6 || month == 11){
        return 30;
    }else if(month == 2){
        if(isLeap(year)){
            return 29;
        }
        return 28;
    }
    return 31;
}

console.log(dayPerYear(2018, 5, 233));
</script>
</body>
</html>