華師 PTA 2020程式設計基礎實驗作業題目集 程式設計題 #10 AC

2020-11-06 12:03:51

第十題
3-9難度係數1 列印菱形圖案 (5分)
3-9難度係數1 列印菱形圖案 (5分)
這道題完美的詮釋了什麼叫格式
先來觀察輸出的格式
輸出的菱形
這裡是輸入7,輸出這個菱形
菱形的上下對稱
每一行的 「*」 數量均為奇數
很自然我們想到遞迴
遞迴
這裡簡單解釋一下遞迴
將一個運用遞迴的函數f(x),根據再次呼叫f(x)的語句,分為上下兩部分,如圖
遞迴解釋
比如這個函數f(x)

void f(int x){
	cout << x << endl;
	if(x != 1){
		f(x - 1);
		cout << x << endl;
	}
}

當輸入x = 4,呼叫f時

//遞 部分
f(4)//第一次呼叫
cout << 4 << endl;
	f(4 - 1)//第二次呼叫
	cout << 3 << endl;
		f(3 - 1)//第三次呼叫
		cout << 2 << endl;
			f(2 - 1)//第四次呼叫
			cout << 1 << endl;
				//此時x = 1,if條件判斷不成立,故遞迴終止
			//歸 部分
		cout << 2 << endl;//第三次呼叫的函數還沒執行結束
	cout << 3 << endl;//第二次呼叫的函數還沒執行結束
cout << 4 << endl;//第一次呼叫的函數還沒執行結束

最後輸出結果是:
4
3
2
1
2
3
4

參考文章對於遞迴有沒有什麼好的理解方法?
有興趣的同學可以實驗一下,將上述f(x)中的if語句中的cout << x << endl;放在if語句之外會發生什麼?

先處理「*」部分

void f(int a, int b){
	//變數a是總行數,作用是規定 遞 的次數,變數b初始值為1,作用的是規定一行輸出多少個「 * 」
    for(int i = 1;i <= b;++i) cout << "*" << " ";//遞 部分
    cout << endl;
    if(a != 1){
        f(a - 2,b + 2);
        for(int i = 1;i <= b;++i) cout << "*" << " ";//歸 部分
        cout << endl;
    }
}

呼叫f(7,1)輸出結果為

* 
* * * 
* * * * * 
* * * * * * * 
* * * * * 
* * * 
* 

有內味了
接下來看空格
輸出的菱形
空格的規律是:6,4,2,0,2,4,6
再看看a的變化規律:7,5,3,1,3,5,7
b變化規律:1,3,5,7,5,3,1
發現,空格數量就是a - 1
運用printf格式輸出

printf("%*s",a - 1,"");

看不懂的看這裡
printf(%*.*f,m,n,f)
printf 「%.*s」

當然也可以使用for來輸出空格

for(int i = 1;i <= a - 1;++i) cout << " ";

再加上輸入語句
這題就解完了

完整程式碼如下

#include<iostream>
#include<stdio.h>
using namespace std;

void f(int a, int b){
    printf("%*s",a - 1,"");
    for(int i = 1;i <= b;++i) cout << "*" << " ";
    cout << endl;
    if(a != 1){
        f(a - 2,b + 2);
        printf("%*s",a - 1,"");
        for(int i = 1;i <= b;++i) cout << "*" << " ";
        cout << endl;
    }
}

int main(){
    int inp;
    cin >> inp;
    f(inp,1);
}

提交結果如下
簡簡單單