列印菱形(Print Diamond/Lozenge)

來源:互聯網
上載者:User
*
* * *
* * * * *
* * *
*

  總結了一下關於列印菱形的思路。

  通常是從迴圈變數之間的映射關係入手,推匯出相應的公式。這種思路的源點,往往會將座標軸的原點放在左上方,也就是在[2N + 1]的矩形內列印出內嵌的菱形。如所示,橫向[row]的取值範圍[0, 2N+1),縱向[col]的取值範圍[0, 2N + 1),變數[N]表示要列印菱形對角線長的1/2。

0 1 2 3 4 5 6
0 *
1 * * *
2 * * * * *
3 * * * * * * *
4 * * * * *
5 * * *
6 *

  照此思路有如下幾種解法:

  解法一:將菱形從中間分開,可以看到[輸出空格數 + 星號數 = N](*從零計數)。那麼可以將空格輸出和星號輸出分別進行。

  [空格輸出]的控制變數由[col]完成。對應的輸出條件[col < abs(row - N)]。

  [星號輸出]的控制變數亦由[col]完成。對應的輸出條件[col < (2 * (N - abs(row - N)) + 1]。

0 1 2 3 4 5 6
0 *
1 * * *
2 * * * * *
3 * * * * * * *
4 * * * * *
5 * * *
6 *

  ★ 代碼如下:

/*    這裡將菱形從中切開,比較容易尋找到規律。*/#include <stdio.h>#include <math.h>int main(void){    int count, row, col;    printf("Number of rows = ?\n");    scanf("%d", &count);    for (row = 0; row < (count * 2 + 1); row++) {        // 控制空格的輸出        for (col = 0; col < abs(row - count); col++) {            printf(" ");        }        // 控制 * 號的輸出        for (col = 0; col < (2 * (count - abs(row - count)) + 1); col++) {            printf("*");        }        printf("\n");    }    return 0;}

  解法二:認為是在一個[2N + 1]的矩形畫布上輸出菱形。鑒於菱形的對稱特性,利用座標之間的不等式關係,可以找到每一個星號的可能的輸出範圍。

  那為例,

  [紅色*座標] [row, col] = [0, 3]  ==>  (row + col) = 3

  [藍色*座標] [row, col] = [6, 3]  ==>  (row + col) = 9

  由此可知 (row + col) ∈ [N, 3 * N]

0 1 2 3 4 5 6
0 *
1 * * *
2 * * * * *
3 * * * * * * *
4 * * * * *
5 * * *
6 *

  但對於兩個變數[row]和[col]而言,顯然一個條件式並不能夠正確的定位,現在需要構建另一個條件式。

  仍以為例,可以得到對應的條件式

  [紅色*座標] [row, col] = [0, 3]  ==>  (row - col) = -3

  [藍色*座標] [row, col] = [6, 3]  ==>  (row - col) = 3

  由上可以推得 (row - col) ∈ [-N, N]

  到這裡兩個控制變數被限制在了兩個條件式中,這時就可以正確的定位到每一個星號的位置了。

  ★ 代碼如下:

#include <stdio.h>int main(void){    int row, col, count;    printf("Number of rows = ?\n");    scanf("%d", &count);    for (row = 0; row < (2 * count + 1); row++) {        for (col = 0; col < (2 * count + 1); col++) {            // 這裡要求輸出 * 的位置滿足[count <= (row + col) <= 3 * count]&&[-count <= (row - col) <= count]            if (count <= (row + col) && (row + col) <= 3 * count && -count <= (row - col) && (row - col) <= count) {                printf("*");            } else {                printf(" ");            }        }        printf("\n");    }    return 0;                                                                               }

  以上兩種解法預設座標系在左上方,實際可以平移座標系,使得橫縱座標之間的關係能夠更好的表達。如

-3 -2 -1
-3 *
-2 * * *
-1 * * * * *
0 * * * * * * *
1 * * * * *
2 * * *
3 *

  解法三:觀察在新的座標系中,每個星號所在的橫縱座標之間的關係可以表示為[row + col <= N]

  [紅色*座標] [row, col] = [0, -3]  ==>  (row + col) = -3

  [藍色*座標] [row, col] = [3, 0]  ==>  (row + col) = 3

  由此可知 (abs(row) + abs(col)) ∈ [0, N]

  以上兩種解法預設座標系在左上方,實際可以平移座標系,使得橫縱座標之間的數值關係能夠更好的表示。如

-3 -2 -1
-3 *
-2 * * *
-1 * * * * *
0 * * * * * * *
1 * * * * *
2 * * *
3 *

  ★ 代碼如下:


/**    靈活運用座標系可以簡化程式。**/#include <stdio.h>#include <math.h>int main(void){    int row, col, count;    printf("Number of row count = ?\n");    scanf("%d", &count);    for (row = -count; row <= count; row++) {        for (col = -count; col <= count; col++) {            if (abs(row) + abs(col) <= count) {                printf("*");            } else {                printf(" ");            }        }        printf("\n");    }    return 0;}

  下面的方法充分利用了[printf函數]本身提供的功能,可以實現極其精簡的代碼。

  解法四:採用通常預設的座標方式來表示變數之間的關係。

映射關係
row 輸出寬度 輸出寬度函數關係 星號個數 模板星號 需要刪除星號個數 刪除星號個數函數關係
0 5 row + N + 1 1 ********* 8 2 * N - 2 * row
1 6 3 6
2 7 5 4
3 8 7 2
4 9 9 0
5 8 (3 * N + 1) - row 7 2 2 * row - 2 * N
6 7 5 4
7 6 3 6
8 5 1 8

  對應的關係列出後,就很容寫出對應的代碼了。

  ★ 代碼如下:

#include <stdio.h>int main(void){    int row, col, count;    int i = 0;    char a[100];    printf("Number of rows = ?\n");    scanf("%d", &count);    for (; i != (2 * count + 1); i++) {        a[i] = '*';    }    row = 0;    for (; row != (2 * count + 1); row++) {        printf("%*s\n", (row < (count + 1)?(row + count + 1):((3 * count + 1) - row)), a + (row < (count + 1)?(2 * count - 2 * row):(2 * row - 2 * count)));    }}

  解法五:採用座標軸平移後的方式來表示變數之間的關係。

映射關係
row 輸出寬度 輸出寬度函數 星號個數 星號模板 要刪除的星號個數 刪除星號個數函數關係
-4 5 (2 * N + 1) - abs(row) 1 (2 * N + 1) - abs(row) - abs(row) ********* 8 2 * abs(row)
-3 6 3 6
-2 7 5 4
-1 8 7 2
0 9 9 0
1 8 7 2
2 7 5 4
3 6 3 6
4 5 1 8

  依上表對應關係,經過座標平移後的對應關係更加簡潔,代碼量更小。

  ★ 代碼如下: 

#include <stdio.h>#include <math.h>intmain(void){    int row, col, count;    int i;    char p[100];    printf("Number of rows = ?\n");    scanf("%d", &count);    i = 0;    for (; i != (2 * count + 1); i++) {        p[i] = '*';    }    row = -count;    for (; row <= count; row++) {        printf("%*s\n", ((2 * count + 1) - abs(row)), p + (2 * abs(row)));    }    return 0;}

 

★ 以上代碼均在 Ubuntu 10.04 下編譯通過。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.