1. 程式人生 > >遞迴,斐波那契數及其取模運算

遞迴,斐波那契數及其取模運算

一、遞迴
1、遞迴:即函式自己呼叫自己,函式在呼叫時會進行引數例項化,開闢棧空間。
2、遞迴可簡化程式碼的編寫。易讀。
3、遞迴必須設定遞迴出口,否則會出現死迴圈
4、遞迴過程需一直開闢棧空間,執行速度慢,效率低。且存在棧溢位問題
5、相比較,迭代(非遞迴)的執行效率更高些,且不會一直開闢棧空間和造成棧的溢位問題,但程式碼書寫量大,易讀性低。

注:對一個數取模等同於對構成那個數的每個數取模,
  列:13=8+5=8+3+2 那麼 13%3=8%3+3%3+2%3=8%3+(3%3+2%3)%3
  為防止每個數取模的和大於模數,所以每兩個數取模之和後再次取模

二、程式碼例項解析(階乘,斐波那契數及其取模運算)

#include<stdio.h>
#include<stdlib.h>

//54321輸出5 4 3 2 1的遞迴執行流程解析
//遞迴是按一層一層的順序執行的.
//只有當最內層執行結束後才執行上一層未執行的語句,每一層都為遞迴函式整體,但每層實際都不相同
//下列(num=5):
//第n次執行表式 print用pn表式
//第n次執行表式 printf用pfn表式
//從外層到內層的順序執行,只有當最內層執行結束後才接著執行上一層未執行的語句,因此最外層是最後執行結束的。
//(p1->( p2->(p3->(p4->(p5->pf5)->pf4->pf3)pf2)pf1)
//p2->(p3->(p4->(p5->pf5)->pf4->pf3)pf2 //p3->(p4->(p5->pf5)->pf4->pf3 //p4->(p5->pf5)->pf4 //p5->pf5 void print(int num)//num=5 { if(num>10)//遞迴出口條件 { print(num/10);//digui. 54321-5432..->5 } printf("%d ",num%10);//5->4->3->2->1 } int main() { int
num=0; printf("put num:"); scanf("%d",&num); print(num); system(" pause"); return 0; } //斐波那契數執行過程(若遞迴有多個return語句可畫圖求解分析) //   change(5)//最終返回5,呼叫9次change()函式 //    /3 +  2\ // change(4) change(3) // / 2+1 \   /  1+1 \ // change(3) change(2)  change(2) change(1) // / 1+1  \     1        1 1 //change(2) change(1) // 1 1 //返回1結束本次呼叫 #include<stdio.h> #include<stdlib.h> //斐波那契數:1+1+2+3+5+8 .... int fbnqs(int num)//求第幾個數的數值,當數值>40時計算速率很慢 { if(num<=2) { return 1; } return fbnqs(num-1)+fbnqs(num-2); //return fbnqs(num-1)%1007+fbnqs(num-2)%1007;//斐波那契數取模 } //對一個數取模等同於對構成那個數的每個數取模, //列:13%3=8%3+3%3+2%3=8%3+(3+2)%3 //為防止每個數取模的和大於模數,所以每兩個數取模之和後再次取模,再加上下個數的餘數,以此類推求出結果 //儲存每個斐波那契數取模後的數而不是斐波那契數 int fbnqsy(int num)//迭代法,對斐波那契數(999)取模(10007) { int a, b, c, i; a = 1; b = 1; if(num < 3) return 1; for(i = 3; i <= num; i++){ c = (a + b) %10007;//前兩個數的餘數+下一個數的餘數, a = b % 10007;//對取模的兩個數再次取模防止之和大於模數, b = c;//前兩個數的餘數, } return c; } int change(int num)//計算結成 { if(num==1)//num==1時,退出函式 { return num; } return num*change(num-1);//遞迴,累乘 } int main() { int num=0; printf("put num:"); scanf("%d",&num); printf("%d \n",change(num)); printf("%d \n",fbnqs(num)); printf("%d \n",fbnqsy(num)); system("pause"); return 0; }

相關推薦

及其運算

一、遞迴 1、遞迴:即函式自己呼叫自己,函式在呼叫時會進行引數例項化,開闢棧空間。 2、遞迴可簡化程式碼的編寫。易讀。 3、遞迴必須設定遞迴出口,否則會出現死迴圈 4、遞迴過程需一直開闢棧空間,執行速度慢,效率低。且存在棧溢位問題 5、相比較,迭代(非

如何使用Python的方法來實現組合數實現

組合數公式: C(n,m)=n!/((n-m)!*m!) 傳統演算法 def CombinationNum(n,m):     #n>=m n,m都是自然數     #找到一個出口     if m == 0 or n == m:         return

斐波那契數是第一個數和第二個數都為1,從第三個數開始,後面的是是前面相鄰兩個數的和。定義的函式如下所示: int fib(int m) {     if (m == 1 || m == 2)         

#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int fib(int n) { int a = 1; int b = 1; int c = 0; if (n <= 2) re

使用實現中的20個月有多少隻兔子

package it.casts.homework; //5.使用遞迴實現斐波那契列數中的20個月有多少隻兔子; public class Test05 { public static void main(String[] args) { int method = method(20);

還在用實現數列面試官一定會鄙視你到死

       斐波那契數列指的是這樣一個數列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368...... &nb

C語言經典演算法(八)——實現數列的兩種方法

後繼續整理演算法並寫出自己的理解和備註。 C++實現的:遞迴實現斐波那契數列 1、 遞迴實現斐波那契數列Fib(n) <1> 題目描述:輸入n值,求解第n項的斐波那契數列值 <2> 方法一:概念法 <3> 方法二:遞迴法 斐波那契數列值是值1

python 方法 數列—漢諾塔

#普通方法生成 def feibo(n): a,b=0,1 print('0,1',end='') for i in range(n-1): a,b=b,a+b print(',{0}'.format(b),end='') #遞迴方法生成 def

python 迭代法和 實現演算法

題目:古典問題:有一對兔子,從出生後第3個月起每個月都生一對兔子,小兔子長到第三個月後每個月又生一對兔子,假如兔子都不死,問每個月的兔子總數為多少? 1.程式分析: 兔子的規律為數列1,1,2,3,5,8,13,21…. 由規律可知: f(n) = f(n-1)+f(n-2) 符合斐波那契數

和非實現數列

斐波那契數列(Fibonacci sequence),又稱黃金分割數列、因數學家列昂納多·斐波那契(Leonardoda Fibonacci)以兔子繁殖為例子而引入,故又稱為“兔子數列”,指的是這樣一個數列:1、1、2、3、5、8、13、21、34、……在數學上,斐波納契數列

Python—用列表和數列

1.生成前10個斐波那契數(Fibonacci),要求將這些整數存於列表L中,最後打印出這些數[1, 1, 2, 3, 5, 8, 13, 21, 34, 55] (斐波那契數的前兩個是1,1,之後的數是前兩個數的和) 方法1:使用列表 L=[1,1] while len(L)<

Java面向物件——用數列

1.用非遞迴方式求斐波那契數列: package Hello; public class Test { public static void main(String[] args) {

有一對兔子從出生後第3個月起每個月都生一對兔子小兔子長到第三個月後每個月又生一對兔子假如兔子都不死問每個月的兔子對數為多少?(數列)

/** * @Desc:古典問題:有一對兔子,從出生後第3個月起每個月都生一對兔子,小兔子長到第三個月後每個月又生一對兔子, * 假如兔子都不死,問每個月的兔子對數為多少? 程式分析: 兔子的規

用for迴圈\遞數列

for迴圈 public class Test{ public static int fib(int n){ if(n == 1 || n == 2){ return 1; }else{ int a = 1; int b = 1; int s = 0; for

Python:輸出數列

今天學習Python的時候做一道練習題,題目是這樣的: 題目 匯入 問題 有一對兔子,從出生後第3個月起每個月都生一對兔子,小兔子長到第三個月後每個月又生一對兔子,假如兔子都不死,問每個月的兔子總對數為多少? 分析 簡單的分析了一下,發現這個問題

數列(兔子總數)。

反覆學習反覆學習。 因為自己對遞迴還是不太熟練,於是做POJ1753的時候就很吃力,就是翻棋子直到棋盤上所有棋子的顏色一樣為止,求最少翻多少次,方法是列舉遞迴。然後就打算先做另一道遞迴的題(從陣列中取

java實現數列

/** *create Date:2016-12-23 *modified Date:2016-12-23 *modified by:shark *Description:斐波那契數列 **/ public class Shulie{public static long d

使用JavaScript實現解決數列及優化

遞迴的概念:若一個演算法直接地或間接地呼叫自己本身,則稱這個演算法是遞迴演算法(《資料結構—使用C語言實現;朱戰立;西安交大出版社》); 遞迴的兩個條件:自己呼叫自己和有結束條件(否則是死遞迴) 斐波那契數列 1, 1, 2,3,5,8,13,21….. 使

數列

#include<stdio.h> long Fib(int n); int count;//計算函式被呼叫的次數 int main() { int n,i,x; printf("Input n:"); scanf("%d",&n); for(i=1;i<=

演算法

1 遞迴   把遞迴想成方法棧,後進先出。遞:一層一層深入(依次執行前置程式碼),直到到達遞迴終止條件(一定要有終止條件,不再執行自己),歸:再從底層一層一層返回(依次執行後置程式碼)。 快速排序:典型的遞迴前置思想,先執行取中分邊,再左右向下遞迴 歸併排序:典型的遞迴後置思想