1. 程式人生 > >遞推遞迴演算法

遞推遞迴演算法

初見安~講深搜前我們先講講遞迴:)

二.遞推

遞推,顧名思義就是根據已有的推出未知的。很簡單,斐波那契數列就是一個很典型的例子:
斐波那契數列
那我們就以此作為例題看看吧:
要求輸入:一個整數n
輸出:斐波那契數列的第n個數。
斐波那契數列的規律也顯而易見:第n個數的值為第n-1個數和第n-2個數的和。

這道題的遞推操作的實現,我們可以用到for迴圈:

#include<iostream>
using namespace std;
int main()
{
	int ans[100],n;//ans儲存數列
	cin>>n;//讀入
	ans[1]=1;//初始化定義,兩個即可
	ans[2]=1;
	for(int i=3;i<=n;i++)//從3開始,避免非法操作。
	{
		ans[i]=ans[i-1]+ans[i-2];	//遞推累加
	}
	cout<<ans[n];//輸出
	return 0;
}

所以遞推是很好理解的:)

三.遞迴

遞迴其實是一個比較大的思想了。它和遞推的區別就在於:遞推是根據一個公式往前推過去,而遞迴則是層層深入,直到邊界後再返回。相當於多了一個回溯的過程。
實現遞迴,我們需要自己定義函式並自身呼叫,即程式巢狀。
這是什麼意思呢?可能有點難理解。簡單舉個例題吧:
求2的x次方。
要求輸入:一個整數x
要求輸出:2的x次方

很簡單的一道題——相信你第一反應是可以用for迴圈來做。為了理解,我們用遞迴實現試試。

先寫好框架吧:

#include<iostream>
using namespace std;
int main()
{
	int x,ans=1;
	cin>>x;
	cout<<digui(x);//digui為自己定義的函式的函式名。
	return 0p;
}

接下來寫自己定義的函式:
void是指無返回值的函式。

void digui(int i)//前文主函式裡的x傳送到這裡,作為變數i——剩下的次方數。
{
	if(i==0) return;//到達邊界,返回。
	ans*=2;
	digui(i-1);
}

如果就這樣了的話,編譯器會告訴你各種沒有定義的錯誤。
首先是void digui(int i)沒有定義。C++在編譯過程中,會有個從上到下的順序,但也會先訪問主函式int main();但在主函式中遇到了一個自定義的函式,就會去查詢——在主函式之前去找。所以我們要把digui定義在主函式前面。
其次就是ans未定義。這裡我們主函式裡定義了,為什麼在自定義函式裡又說沒有定義了?因為就如同上方自定義函式裡的int i一樣,在哪裡定義,就只能在哪裡用。所以int main裡的ans只能在主函式裡呼叫,在digui裡不曾定義。若為了方便,可以定義全域性變數——在主函式外定義。標城如下:

#include<iostream>
using namespace std;
int x,ans=1;//全域性變數
void digui(int i)
{
	if(i==0) return;
	ans*=2;
	digui(i-1);
}
int main()
{
	cin>>x;
	digui(x);
	cout<<ans;
	return 0;
}

這樣我們得到的就是2的x次方了:)

如果有興趣的話,求x的y次方有一個專門的函式:pow(int x ,int y)。有一道題叫做快速冪,是這一方法的一個優化,也可以瞭解一下。畢竟這樣算資料量一旦大了就很容易超時(很久才出結果)。

這一應用上,我們可以發現:遞迴實現的自我呼叫其實可以用for迴圈實現。簡單的遞迴也都的確如此,類似於逆序輸出也可以用for迴圈逆序下標輸出。

我們再來看一個遞迴的應用:
已知:
在這裡插入圖片描述 計算x=4.2,n=10以及x=2.5,n=15時的f的值。
不要覺得你可以手算:)根號這種無理數只能用夾逼法算是很痛苦的。
這道題也很明顯的用遞迴,向自己定義的函式傳資料兩次就可以了。
由這一公式我們也可以化簡為我們的遞推式:
在這裡插入圖片描述
所以我們可以開始敲程式碼了:
P.S:sqrt(int x)為#include中的標準函式,求x的平方根

#include<iostream>
#include<cmath>
using namespace std;
double digui(int x,int n)
{
	if(n==1) return sqrt(x+1);//到達邊界,開始回溯
	return sqrt(digui(x,n-1));//沒有到達邊界,則繼續深入
}

int main()
{
	cout<<digui(4.2,10)<<endl;
	cout<<digui(2.5,15);
	return 0;
}

有沒有突然覺得遞迴很方便呢~這個思想是很簡單的,而難在運用。比如我們下文將講述的——深度優先搜尋(DFS)。

迎評:)
——End——