黑马程序员技术交流社区

标题: 变量范围问题,希望大神给分析一下 [打印本页]

作者: 徐鹏辰    时间: 2015-7-23 14:43
标题: 变量范围问题,希望大神给分析一下
  1. class ArrayTest4
  2. {
  3. public static void main(String[] args)
  4. {
  5.    int[] arr = {2,4,5,7,8,19,32,45};//8

  6.    int index = getIndex_2(arr,190);
  7.    System.out.println("index="+index);}
  8. public static int getIndex_2(int[] arr,int key)
  9. {
  10.    int min = 0,max = arr.length-1,mid;

  11.    while(min<=max)
  12.    {
  13.     mid = (max+min)>>1;

  14.     if(key>arr[mid])
  15.      min = mid + 1;
  16.     else if(key<arr[mid])
  17.      max = mid - 1;
  18.     else
  19.      return mid;
  20.    }
  21.    return min;
  22. }
复制代码

在之前学习中,知道变量有自己的作用域。
而这段代码中最终的min变量,为何不是初始化时的0呢?
它们又有何不同,希望各位大神可以帮帮忙!









作者: wayonEmes    时间: 2015-7-23 14:43
因为你局部变量min是定义在方法中while循环外的,所以它的作用范围是整个方法,min并没有随着while循环的结束而消失,所以return的min是运算后的min,而不是初始的0
作者: 孙晓磊    时间: 2015-7-23 15:54
这是二分法查询啊,
if(key>arr[mid])
     min = mid + 1;
如果你给的key大于输入中间的值就开始给min变值了啊。和变量范围并没有什么关系吧。。
min是getIndex_2的局部变量,这个方法调用完了min也没了啊
详见视频。
054_数组(折半查找)_黑马程序员_Java基础视频
作者: 别急独角戏    时间: 2015-7-23 21:15
if(key>arr[mid])
     min = mid + 1;
这两句执行完后,mid变为4,满足min<=max继续循环,第二次循环min变为6,
满足min<=max继续循环,第三次循环min变为7,
满足min<=max继续循环,第四次循环min变成8,
最终的返回结果为8,这个问题跟变量的作用域没关系,运行代码之前你先自己在纸上写一下,代码都是很严谨的很容易就能得出答案。加油
作者: 徐朋威0716    时间: 2015-7-23 22:01
这是一个这般查找,也叫二分法。
作者: 徐朋威0716    时间: 2015-7-23 22:04
if(key>arr[mid])
      min = mid + 1;
这两句执行完后,mid变为4,满足min<=max继续循环,第二次循环min变为6,
满足min<=max继续循环,第三次循环min变为7,
满足min<=max继续循环,第四次循环min变成8,
最终的返回结果为8,这个问题跟变量的作用域没关系
作者: 我的呸    时间: 2015-7-23 22:06
定义的min在循环里面更改值了吧,所以最后返回的不是初始值0啊。
作者: 小城青年    时间: 2015-7-24 00:29
在折半查找的时候,当key大于mid的时候,就要把最小值改变到mid+1了;
比如在1-100间查找70.做法就是先跟50比,70比50大,自然就是从51到100折半再查找了.这时候最小值就要改成50+1了.
作者: 宋明文    时间: 2015-7-24 23:27
别急独角戏 发表于 2015-7-23 21:15
if(key>arr[mid])
     min = mid + 1;
这两句执行完后,mid变为4,满足min

正解,一直在循环嘛。min一直在+1.最终就变成答案了。。。。
作者: 宋明文    时间: 2015-7-24 23:42
宋明文 发表于 2015-7-24 23:27
正解,一直在循环嘛。min一直在+1.最终就变成答案了。。。。

:lol是啊
作者: 1158865593    时间: 2015-7-25 00:58
通过二分查找法使min的值在循环语句中改变了吧
作者: 爱马尚    时间: 2015-7-25 04:47
结果应该是4吧,class ArrayTest4  { public static void main(String[] args)  {    int[] arr = {2,4,5,7,8,19,32,45};//8     int index = getIndex_2(arr,190);    System.out.println("index="+index);} public static int getIndex_2(int[] arr,int key) {    int min = 0,max = arr.length-1//7,mid;     while(min<=max)    {     mid = (max+min)>>1;//max+n==7>>1==3      if(key>arr[mid])//190>arr[3]      min = mid + 1;//min=3+1     else if(key<arr[mid])      max = mid - 1;     else      return mid;    }    return min; }
作者: hakey    时间: 2015-7-25 23:29
min=0;这行代码只执行了一次,后面的代码中已经被改变,属于局部变量,在你定义的函数内有用,函数调用完毕就消逝。
作者: skymoon0808    时间: 2015-7-26 16:16
min的变化你是根据你要查找的key在arr[]数组中的范围来确定的,如果key>arr[mid],,min是要重新赋值即:min=(max+min)/2+1的,如果key<arr[mid],min值是不变的,最终循环结束的条件是min>max,min的值在最后赋值的时候可能是0可能是(max+min)/2+1,所以min结束一轮之后是不能被初始化为0
作者: xclyijin    时间: 2015-7-26 18:09
原因是,第一次运算后,得到的min是3,第二次后得到的是4,直到最后已经到数组最后了,得到了8,所以返回的是8;
你的程序应该这样改:
  1. package test;

  2. public class halfCheck {

  3.         /**
  4.          * @param args
  5.          */
  6.         public static void main(String[] args) {
  7.                 // TODO Auto-generated method stub
  8.                    int[] arr = {2,4,5,7,8,19,32,45};

  9.                    int index = getIndex_2(arr,190);//你应该是想查找19,不小心打成190的吧
  10.                    System.out.println("index="+index);}
  11.                  public static int getIndex_2(int[] arr,int key)
  12.                  {
  13.                    int min = 0,max = arr.length-1,mid;

  14.                    while(min<=max)
  15.                    {
  16.                     mid = (max+min)>>1;

  17.                     if(key>arr[mid])
  18.                      min = mid + 1;
  19.                     else if(key<arr[mid])
  20.                      max = mid - 1;
  21.                     else
  22.                             return mid;//当相等的时候返回mid;
  23.                    }
  24.                    return -1;//当跳出while时表示找不到,此时返回-1;
  25.                  }

  26.         }

复制代码


应该跳出while的时候返回的不应该是Mid,而是-1.希望能够给黑马币。。。。

作者: Eil.tea    时间: 2015-7-27 20:26
赋值会改变变量的值,如果不知道变量如何变的,加个断点,一步一步执行,代码不长,很容易就清晰了
作者: kang13    时间: 2015-7-29 00:03
min已经改值了  所以就会变了

作者: 铁蛋    时间: 2015-7-29 16:00
变量的作用域在不同代码提上不一样的,属性级别的,作用域类;方法级别(方法体内)的作用域局限在方法体内
作者: 亦如梦幻泡影    时间: 2015-7-29 23:01
你的min变量是getIndex_2中的局部变量,在调用该方法时,方法中有对min的操作,所以return返回的min是操作后的值,
作者: JustForYou    时间: 2015-7-29 23:36
首先我想说的是这段代码最后少了一个 } (可能是楼主复制掉了)
在调用getIndex的时候,按照程序执行顺序,在执行while的时候,由于判断条件为真,
执行循环体,结果使得min的值发生改变,不再是初始化的0。
如果在数组中找不到要查找的值,就应该返回-1,返回min是什么鬼?
提醒一下:也不能返回0的,因为0是第一个索引值,如果返回0,就说明在数组的第一
个位置上的值与要查找的key相同。
作者: 叫我斯文哥    时间: 2015-7-30 11:10
因为 18 行代码的时候你已经给它重新赋值,它的值已经改变不,求币
作者: boboyuwu    时间: 2015-7-31 23:44
min参与计算了啊 ,你定义了int min=0只是赋给了mid初始值,min参与计算肯定会改变值了
作者: 徐鹏辰    时间: 2015-8-1 11:50
本帖最后由 徐鹏辰 于 2015-8-1 11:52 编辑
wayonEmes 发表于 2015-7-23 14:43
因为你局部变量min是定义在方法中while循环外的,所以它的作用范围是整个方法,min并没有随着while循环的结束 ...

这么简单的问题,我竟然想的那么复杂。我只需要了解一下,代码在内存中的加载过程,就全部解决了!
作者: 徐鹏辰    时间: 2015-8-1 11:51
谢谢大家的帮助!




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