OTHER PAGES

WELCOME

Move your mouse onto the image to see the bravo CSS3 Transition!

2012年5月20日 星期日

[C++] 巢狀迴圈與圖形輸出


最近的資訊課上到了雙層迴圈與圖形的輸出。不管是什麼語言,只要談到「巢狀迴圈」,習題大都與圖形輸出有關。當然,不是"畫圖",倒比較像是"拼圖",用寬度相同的字元把圖形拼出來。

 

從聚寶盆談起

資訊課的時候,有一題「聚寶盆」,他的輸出是這個樣子的:

題目一出來,有的同學就開始輸出了一些很有趣的圖,有平行四邊形,有梯形...而只需要修改一小部分,圖形就截然不同。
我的程式碼如下:
<Code 0>
不過,某同學的答案更漂亮:

<Code 0-修改>



這就引發了我的一個想法......

 

座標化的圖形輸出


先看一個簡單的例子:

<Code 1>
#include<iostream>
using namespace std;
int main(){
    int a,b;
    while(cin>>a>>b){
        for(int y=1;y<=b;y++){
            for(int x=1;x<=a;x++){
                cout<<( /*_ 條件 _*/ ?"*":" ");
            }
            cout<<endl;
        }
    }
    return 0;
}
程式開始時,我們先讀入兩整數a、b,依照條件輸出星號或空白。
在這篇文章裡面,我們要考慮的就是圖中的「條件」。
如果「條件」是true,結果就是a 乘 b 的矩形區域被星號填滿。

那修改條件之前,可以這麼想:
迴圈需要兩個座標,由左而右(通常是 x 座標)、由上而下(通常是 y 座標),那麼就建立一個直角坐標系統,而上圖中所有星號都是第一象限的格子點:
這就好像在座標軸上挖出一矩形區域(1<=x<=a,1<=y<=b)然後作圖。

試試修改條件,讓 x+y 是奇數時才輸出星號,結果會是什麼呢?
<Code 2>
/*條件*/  (x+y)%2==1
動手畫畫看:
Chessboard!

 

更上一層樓

1. 改變座標軸的起始值、終止值

Pretty Simple! 只要在for迴圈的開始處修改即可。
至於把y軸正向改成平常使用的上方亦可如法炮製。

2. 畫座標軸?!

需要一點小技巧,而且會把圖形蓋掉(或是圖形蓋掉座標軸也可以),想想看!作法如下:
<Code 3>
if(x==0||y==0){
    cout<<(x==0?(y==0?"+":"|"):"-");
} else{
//...
}
箭頭呢?這就有點複雜,可以自己設計!
(提示:在進入第一個for前多加1行"^y"、
             執行完x迴圈之後判斷x是否為0再多加1字">x")

2. 綜合運用:絕對值圖形

為求更加方便,可以引入一個函式庫cmath,這樣就可以用abs()來回傳絕對值...。
例如這個圖形,作出來會是什麼?[AJ題改編]

把條件那欄改為"abs(abs(x-2)-3)+abs(abs(y-2)-3)<=3",並且記得引入cmath,你就可以畫出來了!而且...畫上座標軸後感覺更精緻!
Try it!!
<Code 4>
#include<iostream>
#include<cmath>
using namespace std;
int main(){
    int a,b;
    while(cin>>a>>b){
        for(int y=b+1;y>=-b;y--){
            for(int x=-a;x<=a;x++){
                if(x==0||y==0){
                    if(y==b+1){
                        /*畫y箭頭*/
                        cout<<(x==0?"^y":"");
                    }else{
                        /*畫x,y座標軸*/
                        cout<<(x==0?(y==0?"+":"|"):"-");
                    }
                } else{
                    cout<<( abs(abs(x-2)-3)+abs(abs(y-2)-3)<=3 ?"*":" ");
                }
            }
            /*畫x箭頭*/
            cout<<(y==0?">x":"");
            cout<<endl;
        }
    }
    return 0;
}

完!

張貼留言