Java--平面图形M打印(通用版)

这是一道面试题,题目就是 打印图形 ,图形类似于:


M


用数字填充后,效果如下:




注意,对称关系也要求的话,还要判断数字的长度,比如,数字超过9的话,后面的数字打印空格的时候,就要打印两遍(两位数),如果数字超过99的话,逢空格就要打印三遍(三位数),依次类推。


遇见这种数字图形打印题的时候,一般不要慌,又不是3D的图形,只要是平面的图,我们都转化为二维数组的思想去存下平面图形中的每个点(数据),比如常见的五子棋的棋盘,就是一个典型的二维数组,每个棋子都是一个(x,y)坐标,对应一个二维数组里面的数据(arr[x][y]),因此,我们在excel表格中,绘制一个简单的M平面图,并简单查找规律总结如下:




规律总结:

(1)横向(X)的坐标,始终都是在递增,横向表示平面图形的列

(2)纵向(Y)的坐标,有两个状态,递增和递减,因此,我们需要一个状态控制判断是递增还是递减

(3)我们发现,行和列的关系存在:  row = (col/4) + 1

(4)我们还要思考,数字的占位问题(对称),也就是每一行每一列,那些没有填充数字的部分,究竟要打印多少了数字占位符(空格),其实,这个很容易分析,一位数,占一个空格,两位数,占两个空格,三位数,占三个空格,依次类推下去.........


根据以上规律,我们直接上demo:


public class MPrint {

	public static void main(String[] args) {

	/*
            003000700
	    020406080        -->任何这种打印的面试题,都化解为二维数组 找规律,解决
	    100050009
                |
                |
                V
             3  7  
            2 4 6 8 
            1   5  9

       */
		
	   Print(125); //传入列 也就是 要展示 多少个数
	}

	
	public static void Print(int col){
			       
		int row = col/4 + 1 ;   //行 根据规律,找到row 和 col 的 关系式 
		
		int x = 0 ;      //x坐标 横向 代表 列
		int y = row -1 ; //y坐标 竖向 代表 行   1 最开始的行索引 为 row -1  
		
		boolean oper = false; //判断y是否 ++  还是 -- 一上来 先--
		
		int[][] arrM = new int[row][col]; //定义一个二维数组,有行有列
		
		//填充数字 注意,不符合条件的,将被填充0
		
		for(int i = 1; i <= col; i++){
			
		    arrM[y][x] = i;
			
		    if(!oper) y--;
		    if(oper)  y++;
				
		    if(y<0)      //证明此时 y = -1 由于碰到头0出去了(减过头了),所以需要拉回来2格,同时进行y++操作
			{
			  y = y+2 ;  
			  oper = true; //操作置为true  表示y++(减过头了,肯定要++)
			}
			
		    if(y>row -1) //证明此时 y = row 由于碰到头row-1出去了(加过头了),所以需要拉回来2格,同时进行y--操作
			{
			  y = y-2 ;
			  oper = false;//操作置为false  表示y--(加过头了,肯定要--)
			}
			
		    x++; //列始终是++
		    
		}//end for
						
		
		//打印二维数组的值  即平面图形 M
		for(int r =0 ; r < row; r++){
					
			for(int c = 0 ; c < col; c++){
			  int cycle = 1; //循环打印空格次数 默认1次(1-9)
				
			/*
			     列索引从0开始,因此,索引9放的是10,     以后每一个都要占两位
			                                  因此,索引99放的是100,以后每一个都要占三位
			             ............................占四位
			  9后面两个空格,99后面三个空格,999后面四个空格,依次类推
			 */

			  if(c>=9)   cycle = 2;
			  if(c>=99)  cycle = 3;
			  if(c>=999) cycle = 4;//这个打印几个空格的规律暂时没有想到更好的表达式代替,暂且多if判断
			  	
				
				
			  if(arrM[r][c] == 0){ //遇到0 打印空格
					while(cycle>0){//循环打印空格 打印几个由cycle的值决定
					   System.out.print(" ");
					   cycle--;
					} 					  		    
			  } 
			  else{ //如果不是0,原封不动的打印数值,此时数值前面已经有了空格填充
				 
				    System.out.print(arrM[r][c]);	
			  } 
			}
			System.out.println();//每一行结束后,记得打印换行
		}
	}
}


demo中我们测试125个数的平面图显示,最后的结果,非常壮观,截取后半部分效果图如下:




关于打印空格的算法可以优化,有兴趣的可以尝试一下。


关于算法--------------->  思路很重要!


没事,多画画,多写写,找找规律,如果程序解决不了(一时半会写不了代码),那我们就把实现的伪代码写出来,走一遍整个流程,然后,再慢慢去修改我们的伪代码,一步步实现我们想要的结果,本篇就是这样的思路,一步步完善最终的Demo,没有绝对的天才,一上来就能一气呵成,我们恰恰需要的是沉淀,积累学习的经验,这才是学习的精髓所在!




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值