黑马程序员技术交流社区

标题: 讨论第二期打印图形的实现方法 [打印本页]

作者: 付莹    时间: 2012-11-29 15:55
标题: 讨论第二期打印图形的实现方法
运行程序:输入3,打印出如下图像:

1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 1 1 1 1

附件是我的实现思路。望高手跟帖,学习牛人的实现方法。

黑马-付莹.rar

946 Bytes, 阅读权限: 10, 下载次数: 24


作者: 马海保    时间: 2012-11-29 16:12
/*思路
                 * 1、从题目图中可以看出,输入3打印出5行5列矩形,如参数为num,则打印出(2*num-1)列和行
                 * 2、在(2*num-1)列和行的矩形中,从矩形的左下角至右上角把矩形分为左右两部分(两部分不相等),
                 *    分别找出左边两部分各自的规律,从而合并后逐个单元格输出
                 */
               
                /*算法思想
                 * 1、输入参数为num,打印出(2*num-1)列和行的矩形
                 * 2、双重for循环打印矩形,分别为i和j(i代表行索引,j代表列索引,默认值都为1,最大值为(2*num-1))
                                   1 1 1 1 1
                                 1 2 2 2   1
                                 1 2 3   2 1
                                 1 2   2 2 1
                                 1   1 1 1 1
                 * 3、打印矩形时,观看上图,从矩形的左下角至右上角把矩形分为左右两部分(两部分不相等),
                 *                注:每个单元格的值1<=k<=num
                 *    1> 在左部分中的每个单元格的值,为当前行索引和列索引中的最小值
                 *    2> 在右部分每个单元格的值,都小于行索引和列索引,并且存在(2*num-k)>=(行索引和列索引)
                 *    3> for循环num次,根据1>2>两条规律输出当前单元格的值
                 */   
               
               
                System.out.println("请输入一个大于0的数字:");
                Scanner input=new Scanner(System.in);
                //接收输入参数
                int num=input.nextInt();
                int max=2*num-1;        //矩形的行数和列数
               
                //打印矩形
                for(int i=1;i<=max;i++)
                {
                        for(int j=1;j<=max;j++)
                        {
                                for(int k=num;k>=1;k--)
                                {
                                        if(i>=k && j>=k && i<=2*num-k && j<=2*num-k)
                                        {
                                                System.out.print(k+" ");
                                                break;
                                        }
                                }
                        }
                        System.out.println("");
                }




这是我的做法,相对你的可能稍微简单点吧,思路和算法思路都有,可能写的不够详细,有一个地方不好理解!我是一步一步推理出来,最后总结成一个if条件。
作者: 王震阳老师    时间: 2012-11-29 20:20
  1. /*
  2. 该程序的思想主要是基于三重循环的方法,
  3. 第一个循环控制二维图形的层数(比如参数是3,则一共有三层);
  4. 第二个循环
  5. */
  6. class MyAnswer
  7. {
  8.         public static void main(String[] args)
  9.         {

  10.         run(3);sop("\r\n");//为了验证正确性,循环测试了多次,多个数据
  11.         run(5);//测试结果
  12.                
  13.         }
  14.         public static void sop(Object obj)
  15.         {
  16.                 System.out.print(obj);
  17.         }
  18.         public static void print(int[][] num)//用于打印数组
  19.         {
  20.                 for(int i=0;i<num[0].length;i++)
  21.                 {
  22.                         for(int k=0;k<num[0].length;k++)
  23.                         {
  24.                                 sop(num[i][k]);
  25.                         }sop("\r\n");
  26.                 }
  27.         }
  28.         public static void run(int x)//用于给数组赋值,给函数为核心函数,主要功能由此产生
  29.         {
  30.                 int rows=x*2-1;//定义行数,由于图形是正方形的,因此行数和列数是一致的。
  31.                 int[][] num=new int[rows][rows];//定义一个二维数组
  32.                 for(int t=0;t<x;t++)//第一个循环:控制层数
  33.                 {
  34.                         sop("第"+(t+1)+"步:"+"\r\n");
  35.                         for(int i=t;i<rows-t;i++)//第二层循环:控制给指定数组要赋值的行数。先给每行数组赋值是相同的,然后通过第一个循环在一次缩小范围赋值
  36.                         {
  37.                                 for(int k=t;k<rows-t;k++)//第三层循环:给数组赋值
  38.                                 {
  39.                                         num[i][k]=t+1;
  40.                                 }
  41.                         }print(num);//打印给数组,为了更好地展示赋值的过程,在这里打印数组结果。
  42.                         sop("\r\n");
  43.                 }
  44.                 sop("您输入的参数为:"+x+"的结果已经打印完毕,并且在最后打印结果的上面显示了计算步骤。");
  45.         }
  46. }
复制代码

打印回字过程显示.jpg (39.55 KB, 下载次数: 28)

打印回字过程显示.jpg

作者: 石琪    时间: 2012-11-29 20:40
  1. /*
  2. 需求:输入任意数字,输出中央数字最大,每层向外递减的数字矩阵
  3. 输入3,如图:
  4.                 11111
  5.                 12221
  6.                 12321
  7.                 12221
  8.                 11111
  9. 分析:
  10.         观察发现此图型像金字塔的俯视图,可用十字坐标系描述每个数字的“坐标”,中心值为“0,0”点
  11.         数值在此坐标系中的特点:1,每行初始值都是1。  2,每行有最大值   3,变量递增至最大值   4,最后一个最大值出现后开始递减
  12. 思路:
  13.         可以用嵌套循环描述坐标变化
  14. */

  15. import java.lang.Math;


  16. class jinzita
  17. {
  18.         public static void main(String[] args)
  19.         {
  20.                
  21.                  int mid = 5;//设置中央值
  22.                 int val = 0;//当前坐标变量
  23.                 int max_x = mid-1;//设置x坐标最大值
  24.                 int min_x = 1-mid;//设置x坐标最小值
  25.                 int max_y = mid-1;//设置y坐标最大值
  26.                 int min_y = 1-mid;//设置x坐标最小值
  27.                 int max = 0;//设置本行最大数
  28.                         while(max_y>=min_y)
  29.                 {
  30.                         //取得本行最大值
  31.                         if(max_y<0)
  32.                         max=max-1;                       
  33.                         if(max_y==0)
  34.                         max=mid        ;
  35.                         if(max_y>0)
  36.                         max=max+1;       
  37.                         val=0;




  38.                         while(min_x<=max_x)//坐标遍历x轴
  39.                         {
  40.                                         if(min_x<0)//坐标在x负半轴
  41.                                 {
  42.                                         if(val<max)
  43.                                                 val=val+1;
  44.                                          System.out.print(val);
  45.                                 }


  46.                                         else if(min_x>=0)//坐标不在x轴负半轴
  47.                                 {
  48.                                         if(min_x<=Math.abs(max_y))//坐标在末尾最大值前,输出本行最大值
  49.                                         {                                                 
  50.                                                 val=max;  
  51.                                                 System.out.print(val);
  52.                                         }
  53.                                          if((min_x>Math.abs(max_y))&(val!=1))//坐标不在末尾最大值前,递减
  54.                                         {
  55.                                                  val=val-1;
  56.                                          System.out.print(val);
  57.                                 }

  58.                                 }





  59.                                 min_x=min_x+1;
  60.                                 }
  61.                         max_y=max_y-1;
  62.                         min_x=1-mid;
  63.             System.out.print("\n");
  64.                 }
  65.         }       
  66. }
复制代码
挺麻烦的,问题搞麻烦了有木有,伤不起啊!
作者: 黑马李勇    时间: 2012-11-29 20:50

  1. /*
  2. 打印出如下图像:

  3. 1 1 1 1 1
  4. 1 2 2 2 1
  5. 1 2 3 2 1
  6. 1 2 2 2 1
  7. 1 1 1 1 1

  8. 思路:
  9.   判断图像得出如下结果。
  10.         如果是3的话 则一行要输出5个数字(或者一列输出5个数字)
  11.         其中以中间为分割线 两边的数是对等的
  12.         在不考虑对等的情况下得出如下图案 1,1,1
  13.                                                                          1,2,2
  14.                                                                          1,2,3
  15.                                                 结论:
  16.                                                    第一行 全部是1            即行数
  17.                                                第二行 两边是1            中间是行数
  18.                                                    第三行 列数小于行数即列数 否则行数
  19.         由此可以知道  行数决定当前行的最大值 不管列数是多少。
  20.                                   当列数小于行数的时候,应输出列数。
  21.                                   当列数大于行数的时候,应输出行数。
  22.         则可以设置两个变量 行x 列y  来实现当前图形
  23.         if(y<x)
  24.                 System.out.println(y);
  25.         else
  26.                 System.out.println(x);

  27.         列的对等处理方法及思路:
  28.                 因为图形存在对等关系 需要对对等进行处理
  29.                 方式如下:
  30.                 判断当前列数是否超过最大值
  31.                         因为是对等关系可以 由 最大值-(列数-最大值)可以得出对等位置的数字
  32.                
  33.         行的对等处理方法及思路:
  34.                 思路与列的对等基本一致

  35. */                       

  36. class Demo
  37. {
  38.         public static void main(String[] args)
  39.         {
  40.                 int num = 3;

  41.                 //上半段
  42.                 for(int x=1; x<=num; x++)
  43.                 {
  44.                         printnum(num,x);
  45.                 }

  46.                 //下半段
  47.                 for(int x=num-1; x>0; x--)
  48.                 {
  49.                         printnum(num,x);
  50.                 }
  51.         }
  52.                
  53.         //因上半段与下半段判断方法一样 故创建一个函数 来简化代码
  54.         public static void printnum(int num,int x)
  55.         {
  56.                 for(int y=1;y<=2*num-1;y++)
  57.                         {
  58.                                 //判断当前列数是否超过最大值
  59.                                 if(y < num)
  60.                                 {
  61.                                         if(y<x)
  62.                                                 System.out.print(y+" ");
  63.                                         else
  64.                                                 System.out.print(x+" ");
  65.                                 }
  66.                                 else
  67.                                 {
  68.                                         if(num-(y-num)<x)
  69.                                                 System.out.print(num-(y-num)+" ");
  70.                                         else
  71.                                                 System.out.print(x+" ");
  72.                                 }
  73.                         }
  74.                         System.out.println();
  75.         }
  76. }
复制代码
这是我的想法和思路...
作者: 康乐    时间: 2012-11-29 22:58
本帖最后由 color 于 2012-11-29 23:02 编辑

  1. /**
  2. 要求:运行程序:输入3,打印出如下图像:
  3.         
  4.         1 1 1 1 1
  5.         1 2 2 2 1
  6.         1 2 3 2 1
  7.         1 2 2 2 1
  8.         1 1 1 1 1
  9. 思路:1、根据以上要求可以看出要想打印出此图形需要大圈套小圈
  10.         即要循环嵌套,行数为2乘以数-1;其中外层循环控制行数
  11.         2、经过分析,以上图形每行没有统一的规律
  12.         3、可以分部打印,将整个图形分为四个象限,以中间的数字3为0坐标
  13.         4、开始画出来,然后总结各个象限的规律:
  14. 总结规律:
  15.         i/j        1列        2列        3列        |4列        5列
  16.         1行        1            1          1          |1            1
  17.         2行        1            2          2          |2            1
  18.         3行        1            2          3          |2            1
  19.         ---------------------------------------------------------------
  20.         4行        1            2          2          |2            1
  21.         5行        1            1          1          |1            1
  22.         1、左上象限:当行数i小于j时,打印的数为i,否则为j
  23.         2、右上部分:参数的2倍减列数大于行数则输出i,否则输出2*3(参数)-列数。
  24.         3、左下部分:参数乘以2-行数i大于列数j则输出j,否则输出2*3(参数)-1。
  25.         4、右下部分:行数i>列数j,则输出2*(参数)-行数i,否则输出2*3-列数。
  26. */
  27. import java.util.Scanner;
  28. public class PrintNum {

  29.         public static void main(String[] args)
  30.         {
  31.                
  32.                 Scanner scanner = new Scanner(System.in);
  33.                 System.out.println("请输入数字");
  34.                 int num = scanner.nextInt();
  35.                 printImage(num);

  36.         }
  37.         public static void printImage(int num)
  38.         {
  39.                 int hang = num*2-1;
  40.                 for (int i = 1;i<= hang ;i++ )
  41.                 {
  42.                         for(int j = 1;j<=hang;j++)
  43.                         {
  44.                                 int tmp=0;
  45.                                 /*判断左上象限的输出内容*/
  46.                                 if(i<=num && j<=num)
  47.                                 {
  48.                                         tmp = i<j?i:j;
  49.                                 }
  50.                                 /*判断右上象限的输出内容*/
  51.                                 if(i<=num && j>num)
  52.                                 {
  53.                                         tmp = 2*num-j>i?i:2*num-j;
  54.                                 }
  55.                                 /*判断左下象限的输出内容*/
  56.                                 if(i>num && j<=num)
  57.                                 {
  58.                                         tmp = 2*num-i>j?j:2*num-i;
  59.                                 }
  60.                                 /*判断右下象限的输出内容*/
  61.                                 if(i>num && j>num)
  62.                                 {
  63.                                         tmp = i>j?2*num-i:2*num-j;
  64.                                 }

  65.                                 System.out.print(tmp+" ");
  66.                         }
  67.                         System.out.println();

  68.                 }
  69.         }
  70. }
复制代码
找到规律就好了。
作者: 纪艺松    时间: 2012-11-29 23:29

* 思想:最中心的为n,然后从里往外算第一个外圈为n-1,然后从里往外算第二个外圈为n-2.....;直到从里往外算的最后一个
* 外圈为1;
* */
public class outPut {
        public static void main(String[] args){
                matrix(3);//调用函数
               
        }
       
        static void matrix(int n){
       
                int matrix[][] = new int[2*n-1][2*n-1];
                int k=1;
       
               
                matrix[n-1][n-1] = n;//给最中心的数赋值n;
               
                //从最中心的往外开始每一个外圈依次赋值n-1,n-2,....1;
                while(n-k>0){
                        for(int col=n-1-k; col<n+k; col++){
                                for(int row=n-1-k; row<n+k; row++){
                                        if( col==n-1-k||row==n-1-k||col==n-1+k||row==n-1+k){
                                                matrix[col][row]=n-k;                           
                                        }
                                }
                        }
                        k++;
                       
                       
                }
               
                //输出矩阵
                for(int i=0; i<2*n-1; i++){
                        for(int j =0; j<2*n-1; j++){
                                System.out.print(matrix[i][j]+"  ");
                        }
                        System.out.println();
                }
               
        }
}





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2