數字菱形圖案(繪製圖形題的通用思路解法)(C++)

數字菱形圖案(雙重循環)(C++)

//找到一道比較有表明性的,較爲全面的繪製圖形,而且控制繪製字符在變化的題目,驚喜。ios

【問題描述】
編程打印用數字構成的菱形圖案,菱形上半部分的行數n( 1<n<10 )從鍵盤輸入,總行數爲2n-1。圖案的樣式按下面的樣例。編程

【輸入形式】
從鍵盤輸入包括中間一行在內的菱形上半部分的行數n ( 1<n<10 )。函數

【輸出形式】
輸出用數字構成的菱形圖案,樣式按下面的樣例,其中各數字間用1個空格間隔,中間一行的起始數字1位於第1列。測試

【樣例輸入】
4spa

【樣例輸出】code

1
    1 2 1
  1 2 3 2 1
1 2 3 4 3 2 1
  1 2 3 2 1
    1 2 1
      1

解題思路(繪製圖形的題套用)

  1. 把圖形分塊:(不是惟一分塊法)ip

    1|
         1 2| 1
       1 2 3| 2 1
     1 2 3 4| 3 2 1
     ——————————————
       1 2 3| 2 1
         1 2| 1
           1|
  2. 把分紅四塊的菱形,每塊三角形單獨寫出代碼(通用循環格式:for循環,i表示行數,j表示列數)ci

先給出完整代碼:io

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
    int n;//上半部分行數
    cin >> n;

    for( int i=1; i <= n; ++i )
    {
        cout << setw( 2*(n-i)+1 );//打印空格

        for( int j=1; j <= i; ++j )//左上三角形
            cout << " " << j;

        for( int j=i-1; j > 0; --j )//右上三角形
            cout << " " << j;

        cout << endl;//一行結束換行
    }

    for( int i=1; i <= n-1; ++i )
    {
        cout << setw( 2*i+1 );//打印空格

        for( int j=1; j <= n-i; ++j )//左下三角形
            cout << " " << j;

        for( int j=n-i-1; j > 0; --j )//右下三角形
            cout << " " << j;

        cout << endl;//一行結束換行
    }
}

詳解:
左上三角形:
(TIP:先行提醒一下setw()的用法,不是調用setw(6)就空6個空格,而是表示設域寬爲6個字符,若是後面連續輸出其餘字符,這會在域寬中從右到左覆蓋「空格」)for循環

//能夠本身用如下這個代碼自行體驗測試
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
    int a=6;
    cout<<setw(1)<<a<<endl;
    cout<<setw(2)<<a<<endl;
}
#include <iostream>
#include <iomanip>//使用控制符時,要在程序的頭上加專門的頭文件
using namespace std;

int main()
{
    int n;
    cin >> n;//接下來以用戶輸入的n是4,即樣例輸出的菱形來作說明
    for( int i=1; i <= n; i++ )//做爲左上三角形,行數明顯與n同樣,因此使i循環n次
    {
        cout << setw( 2*n-2*i+1 );//setw()即設域寬爲()個字符,數格子找規律
        //(找規律的詳解見代碼結束後的表格)
        for( int j=1; j <= i; j++ )//定義列數j和每列輸出的字符
            cout << " " << j;//注意題目要求是每一個字符之間都有空格
        cout << endl;//換行不能在for j 的循環裏面,應該是每徹底輸出一行,才考慮換行
    }
}

以n=4爲例:

行數i 空格數
1 7
2 5
3 3
4 1

廣泛推廣到n:
(注意:空格數確定是跟n和i有聯繫的,就往這上面湊)

行數i 空格數
1(1=n-(n-1)) 2*(n-1)+1
2(2=n-(n-2)) 2*(n-2)+1
n-2 5
n-1 3
n 1

歸納的規律:
空格數=2*(n-i)+1
即setw(2*(n-i)+1)
(後面幾個找規律都是按這樣的思路來一一列表找,以後就再也不如此反覆地解釋)

右上三角形:

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
    int n;
    cin >> n;
    for( int i=1; i <= n; i++ )//行數循環
    {
        //注意,以左上的三角形爲參考,則右上的三角形第一行不能輸出東西,在第二行纔開始輸出
            for( int j=i-1; j > 0; j-- )//列數j循環,並且我不想再多設置一個變量,就直接把j看成輸出的東西一塊兒來循環
            //首先要保證循環的列數是從1到i-1,其次要保證輸出的字符是左邊三角形最大的數減1的那個數(即i-1)
                cout << " " << j;
            cout << endl;
        }
    }
}

左下三角形:

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
    int n;
    cin >> n;
    for( int i=1; i <= n-1; i++ )//只要輸出n-1行
    {
        cout << setw( 2*i+1 );//每行前面的「空格」找規律(確定是一個與i有關的式子)
        for( int j=1; j <= n-i; j++ )
            cout << " " << j;
        cout << endl;
    }
}

右下三角形:

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
    int n;
    cin >> n;
    for( int i=1; i <= n-1; i++ )
    {
        for( int j=n-i-1; j > 0; j-- )//同右上三角形,不只j控制列數循環次數,並且控制輸出字符,找個規律就很容易得答案了
            cout << " " << j;
        cout << endl;
    }
}
  1. 模塊組合:咱們把以上四個小塊組合在一塊兒,就很容易獲得完整的菱形了。
    **思路:**上下關係的模塊在main()函數內按順序並列排,左右關係的模塊在for i 循環內按順序並列排,先內左右,後外上下,刪除相同的代碼,保留不一樣的部分。

模塊關係解釋:

左上爲 ① 右上爲②
左下爲③ 右下爲④

則①②爲左右關係,③④也爲左右關係,①②與③④則爲上下關係。

PS:這樣就搞定了
推廣用法,菱形是比較全面的模型:

  1. 若是隻是輸出左上三角,左下三角,怎麼組合代碼呢?
  2. 若是不輸出數字,而所有用「#」代替會變化的數字輸出,怎麼改代碼呢?
  3. 若是每一個輸出字符之間不要留空格,怎麼尋找循環規律呢?
  4. 若是打九九乘法表,怎麼組合模塊呢?
相關文章
相關標籤/搜索