問題導入——編寫一個程序,只用兩條輸出語句,生成一個像半個5*5正方形形狀(直角三角形)的#符號圖案:
#####
####
###
##
#
我們可以采用消減法,先把它想象成一個5*5的矩形。
第一行:##### 的實現代碼(一個for循環即可)
1 for(int hashNum = 1;hashNum <= 5;hashNum++) 2 { 3 printf("#"); 4 } 5 printf("\n");
所以,要想打印出一個5*5的矩形,只需將上述代碼循環5次即可,即:
1 for(int row = 1;row <= 5;row++) 2 { 3 for(int hashNum = 1;hashNum <= 5;hashNum++) 4 { 5 printf("#"); 6 } 7 printf("\n"); 8 }
到目前為止,我們可以打印出一個5*5的矩形了,已經接近最終的解決方案了。
那麼,接下來應該怎樣修改代碼,使它產生半正方形的圖案呢?
如果我們觀察上面的程序清單並把它與自己所需要的半正方形的輸出進行比較,可以發現問題在於條件表達式hashNum <= 5上。這個條件產生了5個相同的、由5個#符號所組成的行。所以我們需要一種機制,調整每行所生成的符號數量,使第一行為5個符號,第二行為4個符號,以此類推。
接下來,我們要進行另一個消減程序的試驗:寫一段代碼,功能:顯示數字從5到1,每個數字出現在單獨的一行中
分析:我們必須找到一種表達式,在第一行時其值為5,在第二行時其值為4,接下來以此類推。如果我們需要一個當行號遞增時其值遞減的表達式,首先想到的可能是在行號前面加個符號,相當於把它乘以-1.這種方法可以產生遞減的數字,卻不是我們所需要的數字。我們可以把對問題的分析通過一張表格來總結下
行號
所需的值
行號*-1
行號與所需值之差
1
5
-5
6
2
4
-4
6
3
3
-3
6
4
2
-2
6
5
1
-1
6
差是一個固定值6。這意味著我們所需要的表達式是 row*-1 + 6。簡化為6 - row。
所以“顯示數字從5到1,每個數字出現在單獨的一行中”的代碼為:
1 for(int row = 1;row <= 5;row++) 2 { 3 printf("%d\n",(6-row)); 4 }
所以打印半個5*5正方形形狀(直角三角形)的#符號圖案的完整代碼為
1 #include<stdio.h> 2 int main() 3 { 4 for(int row = 1;row <= 5;row++) 5 { 6 for(int hashNum = 1;hashNum <= 6-row;hashNum++) 7 { 8 printf("#"); 9 } 10 printf("\n"); 11 } 12 }
問題延伸——編寫一個程序,只用兩條輸出語句產生一個類似側三角形形狀的#符號圖案:
#
##
###
####
###
##
#
根據前一個問題的分析,我們知道做法如下:
1,使用一個循環,顯示一行特定長度的符號。
2,使用嵌套循環顯示一系列的行。
3,使用代數表達式而不是固定值,為每一行創建不同數量的符號。
4,通過試驗和分析,發現正確的代數表達式。
解決各形狀問題所需要的各個組成部分
##### ##### 5
#### ##### 4
### ##### ##### 3
## ##### 2
# ##### 1
# #### 1
## #### 2
### #### 3
#### #### #### 4
### #### 3
## #### 2
# #### 1
解決“側三角形”問題所需要的各個組成部分
1 7 3 3 #
2 6 2 2 ##
3 5 1 1 ###
4 4 0 0 ####
3 3 -1 1 ###
2 2 -2 2 ##
1 1 -3 3 #
(a) (b) (c) (d) (e)
分析:在“半正方形”問題中,用一個較大的整數減去行號是可行的,所以我們這次用8 - row(行號)得到(b)的結果,但這並不是我們想要的。在前一個問題中,我們需要從大到小的數而不是從小到大的數,因此用一個較大的數減去循環變量就可以了。在這個問題中,我們先是從小到大然後再從大到小。可以試著找到一個中間值,所以我們把前面的8 - row 替換成4 - row,可以得到(c)的結果。這個結果也不正確,但是如果忽略最後3個數左邊的負號,它就是我們所需要的結果。如果我們使用絕對值函數去掉這些負號會怎麼樣?表達式abs(4 - row)產生結果(d),就是我們想要的結果了。
延伸分析:如果我們是對空格而不是#號進行計數會怎麼樣呢?(d)列就是我們對空格進行計數的正確的值序列。為了得到正確數量的#符號,可以把每行看成有4個格子,然後減去空格的數量。如果每行有4個格子,其中abs(4 - row)為空格的數量,則具有#符號的格子的數量就可以用4 - abs(4 - row)獲得。
代碼如下:(注意調用abs函數時要提前添加stdlib.h頭文件)
1 #include<stdio.h> 2 #include<stdlib.h> 3 int main() 4 { 5 for(int row = 1;row <= 7;row++) 6 { 7 for(int hashNum = 1;hashNum <= 4-abs(4 - row);hashNum++) 8 { 9 printf("#"); 10 } 11 printf("\n"); 12 } 13 }
如果再次遇到類似的圖案輸出類問題,以上這套組合拳還是非常有效的!^_^