Java算法之输出“菱形”

Java算法之输出“菱形”


导语:今天和同事聊天,他提到一道面试题,题目大体是,使用控制台输出一个菱形(边长相等),并且每行都是奇数个,怎么写?

首先要审题,1、控制台输出菱形 2、每行是奇数个。

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

上图是需要输出的结果。

分析:如何构建一个菱形?

大体上分3步:
第一步:画出一个直角的梯形:

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

第二步:把该梯形的右下“脚”去掉!

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

第三步:将左边的部分*替换成空格:

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

通过以上三步即可构造成一个菱形,问题解决。

下面说一下具体的思路。
第一步的实现:
这一步其实很简单,首先根据传入的奇数(number=11)来确定第一行要输入的[星号]的个数(columnFirst),为columnFirst = (number/2) + 1;以下每一行加一个[星号]即可,详细代码如下:

public void printDiamond(int number) {
            final int total = number / 2 + 1;// 首行的列数
            for (int row = 1; row <= number; row++) {
                int count = total + (row - 1);// 每行需要的列数
                for (int column = 0; column < count; column++) {
                    System.out.print("*");
                }
                System.out.println();// 换行
            }
}

以上代码即可实现输出步骤一中的直角梯形。

第二步的实现:
从第一步到这一步需要发现一条规律,即:

******                     1
*******                    2
********                   3
*********                  4
**********                 5
***********                6
************(2*1)=2        7
*************2*2=4         8
**************2*3=6        9
***************2*4=8       10
****************2*5=10     11

上图中,第6行是整个菱形的中间,星号数量为11个,本来从第6行起,应该逐个递减,每行递减1个星号,可第7行(和第6行相比)却多了一个星号,这一多一少就是多了1x2=2个星号;第8行(和第6行相比)应该去掉2个星号,可现实是多了2个星号,这一多一少就是多了2x2=4个星号;第9行(和第6行相比)应该去掉3个星号,可现实却是多了3个星号,这一多一少就是多了3x2=6个星号;以此类推。可以发现:从第7行开始,7减去中间值6等于1,8减去中间值6等于2,9减去中间值6等于3,以此类推,可以发现:(行数-中间值(6))乘以2即为需要去掉的右下“脚”。具体代码如下:

public void printDiamond(int number) {
            final int total = number / 2 + 1;// 首行的列数
            for (int row = 1; row <= number; row++) {
                int count = total + (row - 1);// 每行需要的列数
                if (row > total) {
                    count = count - (2 * (row - total));
                }
                for (int column = 0; column < count; column++) {
                    System.out.print("*");
                }
                System.out.println();// 换行
            }
        }

以上代码即可实现输出步骤二中的去掉直角梯形的右下“脚”。

第三步的实现:
从第二步到第三步还需要发现一个规律,即:

******5             1
*******4            2
********3           3
*********2          4
**********1         5
***********0        6
**********1         7
*********2          8
********3           9
*******4            10
******5             11

上图中,需要把左边多余的星号替换成空格,第一行需要替换钱5个空格,第二行需要替换前4个空格,第三行需要替换钱三个空格,以此类推,结合右边的行数会发现:将第一行的行数1减去中间数6等于-5,取绝对值之后为5;第二行的行数2减去中间数6等于-4,取绝对值之后为4;…第七行的行数7减去中间数6等于1,取绝对值之后为1;第八行的行数8减去中间数6等于2,取绝对值之后为2;…第十一行的行数11减去中间数6等于5,取绝对值之后为5;以上规律可以发现:行数减去中间数然后取绝对值正好是当前行应该替换成空格的数量。,具体代码如下:

public void printDiamond(int number) {
            final int total = number / 2 + 1;// 首行的列数
            for (int row = 1; row <= number; row++) {
                int count = total + (row - 1);// 每行需要的列数
                if (row > total) {
                    count = count - (2 * (row - total));
                }
                int columnSpace = Math.abs(row - total);// 每行需要的空格数
                for (int column = 0; column < count; column++) {
                    if (column < columnSpace) {
                        System.out.print(" ");
                    } else {
                        System.out.print("*");
                    }
                }
                System.out.println();// 换行
            }
        }

最终控制台输出结果为:

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

问题解决。

END

你可能感兴趣的:(java)