包含多個遞歸調用的遞歸(打印一把標尺)

在需要將一項工作不斷分爲兩項較小的、類似的工作時,遞歸非常有用。

例如:請考慮使用這種方法來繪製標尺的情況。
標出兩端,找到中點並將其標出。然後將同樣的操作用於標尺的左半部分和右半部分。如果要進一步細分,可將同樣的操作用於當前的每一部分。
遞歸方法有時被稱爲分而治之策略(divide-and-conquer strategy)

程序清單7.17使用遞歸函數subdivide()演示了這種方法,該函數使用一個字符串,將該字符串除兩端爲|字符外,其他全部爲空格。
main函數使用循環調用subdivide()函數6次,每次將遞歸層編號加1,並打印得到的字符串。
這樣,每行輸出表示一層遞歸。該程序使用限定符std::而不是編譯指令using,以提醒讀者還可以採取這種方式。
//relen.cpp -- using recursion to subdivide a ruler
#include<iostream>
const int Len = 66;
const int Divs = 6;
void subdivide(char ar[], int low, int high, int level);
int main() {
	char ruler[Len];
	int i;
	for (i = 1; i < Len - 2; i++) {
		ruler[i] = ' ';
	}
	ruler[Len - 1] = '\0';
	int max = Len - 2;
	int min = 0;
	ruler[min] = ruler[max] = '|';
	std::cout << ruler << std::endl;
	for (i = 1; i <= Divs; i++) {
		subdivide(ruler, min, max, i);
		std::cout << ruler << std::endl;
		for (int j = 1; j < Len - 2; j++)
			ruler[j] = ' ';	//reset to blank ruler
	}return 0;
}
void subdivide(char ar[], int low, int high, int level) {
	if (level == 0)
		return;
	int mid = (high + low) / 2;
	ar[mid] = '|';
	subdivide(ar, low, mid, level - 1);
	subdivide(ar, mid, high, level - 1);
}

下面是輸出:
在這裏插入圖片描述
程序說明
subdivide()函數使用變量level來控制遞歸層。函數調用自身時,將把level減1,當level爲0時,該函數將不再調用自己。注意,subdivide()調用自己兩次,一次針對左半部分,另一次針對右半部分。最初的中點被用作一次調用的右端點和另一次調用的左端點。請注意,調用次數將成幾何級數增長。也就是說,調用一次導致兩個調用,然後導致4個調用,再導致8個調用,以此類推。這就是6層調用能夠填充64個元素的原因(26=64)。
這將不斷導致函數調用數(以及存儲的變量數)翻倍,因此,如果要求的遞歸層次很多,這種遞歸方式將是一種糟糕的選擇;然而,如果遞歸層次較少,這將是一種精緻而簡單的選擇。

By《C++ Primer Plus》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章