黑马程序员技术交流社区

标题: 看似简单但是却很诡异的一道题目。求解 谢谢 [打印本页]

作者: 刘宁    时间: 2012-4-22 13:55
标题: 看似简单但是却很诡异的一道题目。求解 谢谢
本帖最后由 刘宁 于 2012-4-22 13:56 编辑

class ArrayTool{
        public static int getMax(int[] arr){
                int max = 0;
                for(int x=0; x<arr.length; x++){
                        if(arr[x]>arr[max]){
                                arr[max ]= arr[x];
                        }
                }
                return arr[max];
        }        
               public static int getMin(int[] arr)
        {
                int min = 0;
                for ( int x=0; x<arr.length; x++)
                {
                        if (arr[x]<arr[min])
                        {
                                arr[min] =arr[ x]; //这里很神奇啊明天问问别人。。。
                        }
                }
                return arr[min];
        }
class ArrayToolDemo{
      public static void main(String[] args) {

                int[] arr = {1,3,4,2,7,22,8,3};
                System.out.println(arr.length);
                int max = ArrayTool.getMax(arr);
                System.out.println("max="+max);
                int min = ArrayTool.getMin(arr);
                System.out.println("min="+min);
      }
}
打印结果是max=22  min=2;很诡异的一道题。请问问什么?
作者: 真真姐    时间: 2012-4-22 14:18
本帖最后由 真真姐 于 2012-10-21 14:43 编辑

                                                           给你看几个图吧,你会很直接的感觉到的,纯手工制作!

                                                           这里教你的是分析问题的解决办法,出现问题了我们用什么逻辑去分析出问题的所在
                                                           一旦逻辑有了,只需要尝试就能找出错误,请看下面的5步!

                                                           1、把getMax方法注释掉后,在方法内部打印发现完全正常,证明这个方法没问题!


                                                            2、把这两句代码调转执行的顺序发现结果正常!


                                                             3、在这里初步判断是数组发生了改变,所以我们尝试测试数组:



                                                               4、 打印发现,数组已经被改变,最小数2;

                                                             5、这时getMin方法再来调用变化的数组,最小值肯定是2;

                                                             6、所以写代码时:要对一个数组进行操作的话,其他地方还要用到这个数组应该这样写:







作者: 邓斌    时间: 2012-4-22 14:21
呵呵。我以前做了。也和你差不都。后来研究了下。OK。这个详解:
你吧自己程序。数组0角标元素改为2或者其他数,其他角标在加个1。还是可以输出1的。
主要是  arr[max ]= arr[x]; 这句话吧0角标赋值为最大值了。//正确的求的话max=x;这样就不会更改数组元素
同样    arr[min] =arr[ x]; 这句话吧0角标赋值为最小值了。//正确的求的话min=x;这样就不会更改数组元素
代码最后面System.out.println(arr[0]);  你可以验证输出时2。。
  1. class ArrayTool{
  2.         public static int getMax(int[] arr){
  3.                 int max = 0;
  4.                 for(int x=0; x<arr.length; x++){
  5.                         if(arr[x]>arr[max]){
  6.                                 arr[max]=arr[x];
  7.                                                                 //因为max初始为0.这样就把0角标的元素变为最大的了,
  8.                                                                 //相当于就是从新定义了0角标元素,赋值为最大值22了。。所以0角标元素是22
  9.                                                                                
  10.                                                 }
  11.                 }
  12.                 return arr[max];
  13.         }        
  14.                public static int getMin(int[] arr)
  15.         {
  16.                 int min = 0;
  17.                 for ( int x=0; x<arr.length; x++)
  18.                 {
  19.                         if (arr[x]<arr[min])
  20.                         {
  21.                                 arr[min] =arr[ x]; //min初始为0。同上,吧arr[0]=arr[min]了。
  22.                                                                 //相当于就是从新定义了0角标元素,赋值为最小值2了,所以0角标元素就是2了。
  23.                         }
  24.                 }
  25.                 return arr[min];
  26.         }
  27. }
  28. class ArrayToolDemo{
  29.       public static void main(String[] args) {

  30.                 int[] arr = {1,3,4,2,7,22,8,3};
  31.                 System.out.println(arr.length);
  32.                 int max = ArrayTool.getMax(arr);
  33.                 System.out.println("max="+max);
  34.                 int min = ArrayTool.getMin(arr);
  35.                 System.out.println("min="+min);
  36.                                 System.out.println(arr[0]);//输出0角标元素。
  37.       }
  38. }
复制代码

作者: 黄业凌    时间: 2012-4-22 14:33
因为你有个地方写错了
class ArrayTool{
        public static int getMax(int[] arr){
                int max = 0; //[b]改成 int max = arr[0]; 用arr数组的第一个元素开始比较
                for(int x=0; x<arr.length; x++){
                        if(arr[x]>arr[max]){ //
                                arr[max ]= arr[x];//你这里是每次遍历两值比较数据值大的给arr[max],那么你原来
                                                       //  int[] arr = {1,3,4,2,7,22,8,3}; 第一次arr[x] = 0 arr[max] = 0; 都对应数组0坐标1 第一次1=1不满足不进入赋值语句
                                                       //  第二次x等于1 arr[x]实际等于3,arr[max]=实际等于1 3>1 注意:都使用进入赋值语句  
                                                       //  arr[max ]= arr[x]; 你把arr数组坐标0的值替换成了arr坐标3的值 现在arr数组元素就是 arr = {3,3,4,2,7,22,8,3};
                                                       //  一直遍历结束 数组的元素值都被替换掉了,你求最大大小值都是使用同一个数组,所以你求最小值的时候是替换后的数组 最小元素为2
                        }
                        /* 改成
                         * if(arr[x] > max){
                         *  max =arr[x];
                         *  }
                         * 最后返回max
                         */
                }
                return arr[max];
        }        
               public static int getMin(int[] arr)
        {
                int min = 0;//改成 int min = arr[0]; 用arr数组的第一个元素开始比较
                for ( int x=0; x<arr.length; x++)
                {
                        if (arr[x]<arr[min])
                        {
                                arr[min] =arr[ x]; //这里很神奇啊明天问问别人。。。
                        }
                        /* 改成
                         * if(arr[x] < min){
                         *  max =arr[x];
                         *  }
                         * 最后返回min
                         */
                }
                return arr[min];
        }
class ArrayToolDemo{
      public static void main(String[] args) {

                int[] arr = {1,3,4,2,7,22,8,3};
                System.out.println(arr.length);
                int max = ArrayTool.getMax(arr);
                System.out.println("max="+max);
                int min = ArrayTool.getMin(arr);
                System.out.println("min="+min);
      }
}
作者: cz373095238    时间: 2012-4-22 14:49
   public static int getMin(int[] arr)
        {
                int min = 0;  // 这里负值写成min = arr[0];  因为你定义的数组比较特殊,第一个即为最小数,判断语句第一次循环,arr[min]没有获得值。
                for ( int x=0; x<arr.length; x++)
                {
                        if (arr[x]<arr[min])  //if(arr[x]<min) {min = arr[x];}return min;//这里无非就是把第一个数假设是最小的,如果你第一个数就最小了 arr[min] 就没得到值
                        {
                                arr[min] =arr[ x]; //这里很神奇啊明天问问别人。。。
                        }
                }
                return arr[min];
        }

作者: 张亮    时间: 2012-4-22 15:52
本帖最后由 张亮 于 2012-4-22 16:02 编辑
  1. public class ArrayToolDemo{
  2.                                       public static void main(String[] args) {

  3.                 int[] arr = {1,3,4,2,7,22,8,3};
  4.                  System.out.println(arr.length);
  5.                  int max = ArrayTool.getMax(arr);
  6.                  System.out.println("max="+max);
  7.                  System.out.print("现在的数组arr是:");//在这里,输出arr数组。看看arr数组当前的元素。
  8.                  for(int i=0;i<arr.length;i++) {
  9.                          System.out.print(arr[i]+" ");
  10.                          }
  11.                          System.out.println();//
  12.                  int min = ArrayTool.getMin(arr);
  13.                  System.out.println("min="+min);
  14.        }
  15. }
复制代码





arr数组,在求最大值以后,元素已经改变了。此时的arr数组的最小值是2。
希望你能明白


作者: 蒋亮    时间: 2012-4-22 15:57
你这两个方法无论先调用哪个,后面调用的那个方法绝对得不到正确的结果。你既然是要获得数组中元素的最大值、最小值,那你就另外再定义一个变量来存放最值就行了,按你的方法,最值继续用数组元素来存放,肯定会改变原数组的内容,调用getMax()方法后,数组中将有两个相同的最大值,而最小值没了。同理,调用getMax()方法后,数组中将有两个相同的最小值,而最大值却没了。
作者: 刘宁    时间: 2012-4-22 20:01
谢谢大家的帮助。我懂了。
作者: 魏征    时间: 2012-4-23 00:33
ArrayTool.getMax(arr)和ArrayTool.getMin(arr)方法被调用时arr数组的0角标被改变了 数组已经发生改变所以是错的
要对两个方法改一下:
public static int getMax(int[] arr)
{
                int max = 0;
                for(int x=0; x<arr.length; x++)
                 {
                        if(arr[x]>arr[max])
                       {
                                max= x;
                        }
                }
                return arr[max];
}        
public static int getMin(int[] arr)
        {
                int min = 0;
                for ( int x=0; x<arr.length; x++)
                {
                        if (arr[x]<arr[min])
                        {
                                min = x;                        
                        }
                }
                return arr[min];
}

我把max和min设置为角标值,还可以设置为数组中的数值,就不在这里写出了,楼主可能没有明确设定为角标值还是数组中数值,有些混淆了




作者: prospect    时间: 2012-4-23 01:00
你的求最大值与最小值是用的是同一个数组,而在你操作求max值时,把上述数组中角标0的值改变成最大值了,以至于,在你再次操作最小值时,就已经把原数组中的最小值给更改了,也就是新数组中的最小值是2,楼主可以定义临时 的int类型变量,用来存储最大值或最小值。




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