菱形问题(java)

由三部分构成:1、各层数需要* 数  2、输入数最大层数 3、绘制菱形

public class Test {
	
	public static void main(String[] args) {
		int num=88;
		show(num);
		
	}
	
	/**
	 * 层数判断
	 * @param num
	 */
	public static void show(int num){
		if(num<=0) {
			System.out.println("剩余为:"+num);
			return;
		}
		
		int step=1;
		int size=0;
		while(true) {
			size=layer(step);
			if(num<size) {
				step--;
				break;
			}
			step++;
		}
		System.out.println("总层数:"+step+"剩余:"+(num-layer(step)));
		draw(step);
	}
	
	/**
	 * 绘制菱形
	 * @param layer
	 */
	public static void draw(int layer) {
		int size=layer*2;
		StringBuffer buf=new StringBuffer();
		for(int i=1;i<size;i++) {
			if(i<layer) {
				for(int num=0;num<(layer-i);num++) {
					buf.append(" ");
				}
				for(int num=0;num<i;num++) {
					buf.append("*");
				}
				
			}else if(i==layer){
				for(int num=0;num<i;num++) {
					buf.append("*");
				}
				
			}else {
				for(int num=0;num<(i-layer);num++) {
					buf.append(" ");
				}
				for(int num=0;num<layer*2-i;num++) {
					buf.append("*");
				}
			}
			buf.append("\n");
		}
		System.out.println(buf.toString());
	}
		
	/**
	 * 各层需要数量
	 * @param num
	 * @return
	 */
	public static int layer(int num) {
		int index=num;
		int sum=0;
		while(true) {
			index--;
			if(index<=0) {
				break;
			}
			if(index==1) {
				sum+=1;
			}else {
				sum+=index*2-1;
			}
			
		}
		sum=sum*2+num*2-1;
		return sum;
	}
}

 

代码非最有方案,还有优化空间。

public class Test {

    public static void main(String[] args) throws Exception {
        drawRhombus(1);
        drawRhombus(10);
        drawRhombus(25);
    }

    /**
     * 获取菱形占用的总星数
     *
     * @param layer 从最顶层到中间层的层数
     * @return
     */
    public static int getAllStar(int layer) {
        return 2 * layer * layer - 2 * layer + 1;
    }

    /**
     * 获取每层的星数
     *
     * @param layer
     * @return
     */
    public static int getLineStar(int layer) {
        return 2 * layer - 1;
    }

    /**
     * 绘制菱形并打印剩余星数
     *
     * @param starNum
     */
    public static void drawRhombus(int starNum) {
        // 菱形从最顶层到中间层的层数
        int layerNum = 0;
        // 使用的星星数
        int usedNum = 0;
        for (int i = 1; true; ++i) {
            int s = getAllStar(i);
            if (s > starNum) {
                break;
            }
            usedNum = s;
            layerNum = i;
        }

        //菱形上半部分(含中间层)
        StringBuilder up = new StringBuilder();
        //菱形下半部分(不含中间层)
        StringBuilder dn = new StringBuilder();
        for (int i = 1; i <= layerNum; ++i) {
            int upNum = getLineStar(i);
            int dnNum = getLineStar(layerNum - i);
            // 对上半部分每行的星星进行偏移
            up.append(repeatChars(" ", layerNum - i));
            // 对下半部分每行的星星进行偏移
            dn.append(repeatChars(" ", i));
            for (int k = 0; k < upNum; ++k) {
                up.append("*");
            }
            for (int k = 0; k < dnNum; ++k) {
                dn.append("*");
            }
            up.append("\n");
            if (i != layerNum) {
                dn.append("\n");
            }
        }
        System.err.println(up.toString() + dn.toString());
        System.err.printf("总星数:%d, 剩余*数:%d\n\n", starNum, starNum - usedNum);
    }

    /**
     * 将给定的字符串重复 n 次,得到一个新字符串
     *
     * @param chars
     * @param n
     * @return
     */
    public static String repeatChars(String chars, int n) {
        String result = chars;
        for (int i = 0; i < n; ++i) {
            result += chars;
        }
        return result;
    }
}

运行结果如下:

 *
  
总星数:1, 剩余*数:0

  *
 ***
  *
   
总星数:10, 剩余*数:5

    *
   ***
  *****
 *******
  *****
   ***
    *
     
总星数:25, 剩余*数:0