【面試題】如何循環打印菱形?

編寫應用程序打印出來下面的菱形,可以使用輸出語句和單個“*”號,空格和換行符。

儘可能多的使用嵌套for循環,儘可能少地使用輸出語句。






*






* * *




* * * * *


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

* * * * * * *


* * * * *




* * *






*




其實很多人害怕的地方就是,我怎麼才能憑空打印出來一個菱形,這麼多空白的地方怎麼辦?

其實很簡單的,我和大家分享我的心得,其實你還是打印的正方形,

只是就像鋪地板一樣,正方形地板的花色有些地方是“白色瓷磚”,有些地方是“星號瓷磚”。

說的進一步具體一些:

# # # # * # # # #
# # # * * * # # #
# # * * * * * # #
# * * * * * * * #
* * * * * * * * *
# * * * * * * * #
# # * * * * * # #
# # # * * * # # #
# # # # * # # # #

看到了這張正方形的圖了嗎?

其實就是我們想要關心的事情:

什麼時候得打印這個符號,什麼時候得打印那個符號?

你怎麼決定呢?其實很簡單,能打印菱形的數量,都是奇數,不可能是偶數的,而且菱形一定是正方形修剪出來的。

所以我們這邊在找規律的時候也非常好找,那就是傳說中的座標系,見下圖:我們要做的就是確定關鍵座標系的邊界值是什麼,

在這條邊界線外面打印什麼,在那條邊界線內部應該打印什麼?

  

OK,既然知道了這樣一個概念了,那麼我們下一步該如何定位這些符號的座標了,你看到了這條邊的特點了嗎?

長和寬都小於等於長度的一半,同時,他們的之和都等於6,

這就意味着:只要小於這兩個座標之和小於6的,都得是空白,或者不是打印菱形用的* 星號。

這樣子一來,我這邊的一個角被我削下來了,我們來看看效果圖。

public static void main(String[] args) {
        
        for(int i = 1 ; i<= 9 ; i++){
            for(int j = 1; j <= 9 ; j++){
                if ( (i<5 && j < 5 && i+j < 6)
                        ) {
                    System.out.print("   ");
                }else {
                    System.out.print(" * ");
                }
            }//end of loop j
            System.out.println();
        }// end of loop i
    }// end of method main



同樣再接再厲,我們看看第二個角的特點是什麼。

首先,長的座標都已經是5以後的了,寬的座標最多不超過5,;

其次,這兩個座標的相減和相加都存在某種規律(你猜到了嗎?):

所以我們繼續削另外一個角。

public static void main(String[] args) {
		
		for(int i = 1 ; i<= 9 ; i++){
			for(int j = 1; j <= 9 ; j++){
				if ( (i<5 && j < 5 && i+j < 6)
						|| (i<5 && j>5 && j-i >=5)
						) {
					System.out.print("   ");
				}else {
					System.out.print(" * ");
				}
			}//end of loop j
			System.out.println();
		}// end of loop i
	}// end of method main
你看,削下來了嗎?

然後我們繼續削掉第三個角,我們來看看第三個角有什麼規律。

是不是長的座標比較小,寬的座標都是從5開始的?

而且他們這兩個座標之間存在着某種聯繫。


所以,削掉第三個角也很簡單。

public static void main(String[] args) {
		
		for(int i = 1 ; i<= 9 ; i++){
			for(int j = 1; j <= 9 ; j++){
				if ( (i<5 && j < 5 && i+j < 6)
						|| (i<5 && j>5 && j-i >=5)
						|| (i > 5 && j < 5 && i-j >=5) 
						) {
					System.out.print("   ");
				}else {
					System.out.print(" * ");
				}
			}//end of loop j
			System.out.println();
		}// end of loop i
	}// end of method main
(有些空格間隙的稍微誤差,所以可能會有些畸形,你就當它是個正方形吧)

那麼第四個角還需要我說嘛?

也按照同樣的道理把它削下來,規律一樣的,原理和以前的一樣。

/**
 * 
 */
package com.java.chapter05;

/**
 * @author Sinbad840628
 * @version 1.0
 * @since 2014.01.13
 */
public class ForLoop_Diamond1 {

	public static void main(String[] args) {
		
		for(int i = 1 ; i<= 9 ; i++){
			for(int j = 1; j <= 9 ; j++){
				if ( (i<5 && j < 5 && i+j < 6)
						|| (i<5 && j>5 && j-i >=5)
						|| (i > 5 && j < 5 && i-j >=5) 
						|| (i > 5 && j > 5 && i+j >=15)
						) {
					System.out.print("   ");
				}else {
					System.out.print(" * ");
				}
			}//end of loop j
			System.out.println();
		}// end of loop i
	}// end of method main

}//end of class ForLoop_Diamond1
這就是最後的菱形。

到了最後你看明白我的程序的用意了嗎?

我們要做的,就是千方百計排除掉不是菱形的座標,讓這些座標打印空白,其他的地方都打印*號。

所以最後的結果就是這個結果。



讓我們回過頭來從新再來看看第一張圖,現在明白了嗎?



這麼做可能比較傻,但是我們來看看二重for循環的代碼量吧

		for(int i = 1 ; i<= 9 ; i++){
			for(int j = 1; j <= 9 ; j++){
				if ( (i<5 && j < 5 && i+j < 6)
					|| (i<5 && j>5 && j-i >=5)
					|| (i > 5 && j < 5 && i-j >=5) 
					|| (i > 5 && j > 5 && i+j >=15)) {
					System.out.print("   ");
				}else 
					System.out.print(" * ");
			}
			System.out.println();
		}
就這麼點。

不過這裏有個缺點,我這邊的數字都是寫死的,如果要求打印一個長度爲11的菱形,或者長度爲5的菱形,

或者乾脆讓用戶輸入一個奇數,然後輸出一個空心或者實心的菱形,你現在知道里面的規律了嗎?


那麼如何打印不同方向的四個三角形就更加不在話下了,你知道怎麼做了嗎?


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章