在Java中,静态变量在递归调用中的行为如何?

huangapple go评论59阅读模式
英文:

How does static variable behave in recursive call in java?

问题

我使用递归方法来计算,并为了跟踪结果,我使用一个全局静态变量来存储结果。尽管我的代码是错误的,因为在考虑基本情况时。根据我的代码,power(2,3) 应该返回 4。如果我使用干运行方法检查。但实际上,ans 变量的值在整个执行过程中只改变一次。我的问题是,为什么 ans 的值没有得到更新,而对于任何幂 n 的值,基数为 2。我的答案总是返回基数值本身。有谁可以调试我的代码并帮助我理解递归方法调用中全局静态变量的行为。

public class Solution {

    static int ans=1;
    public static int power(int x, int n) {
        if(n==0)
            return 1;
        if(n==1)
            return x;
        else
            ans=ans*power(x,n-1);
        return ans;
    }
}
英文:

I am using a recursive method to calculate, and in-order to track the result, I am using, a global static variable to store the result. Although, my code is incorrect, as while considering base case. According to my code, power(2,3) should return 4. If I check using dry run method. But actually, the value of ans variable, changes only once in the whole execution. My question is, that why is the value of ans not getting updated, and for any value of power n , and base being 2. My answer is always returned as base value itself. Can anyone debug my code and help me understand the behavior of global static variable inside recursive method call

public class Solution {

    static int ans=1;
	public static int power(int x, int n) {
		/* Your class should be named Solution
		 * Don't write main().
		 * Don't read input, it is passed as function argument.
		 * Return output and don't print it.
		 * Taking input and printing output is handled automatically.
		 */
        if(n==0)
            return 1;
        if(n==1)
            return x;
        else
            ans=ans*power(x,n-1);
        return ans;
		
	}
}

答案1

得分: 0

代码由于求值顺序不当而无法正确运行。

假设你调用 power(3, 4)

ans = 1
power(3, 4):
  ans=ans*power(x,n-1)  ->  1*power(3,4-1)
  power(3, 3):
    ans=ans*power(x,n-1)  ->  1*power(3,3-1)
    power(3, 2):
      ans=ans*power(x,n-1)  ->  1*power(3,2-1)
      power(3, 1):
        return 3
      ans=1*power(3,2-1) =1*3 =3
      return ans  ->  return 3
    ans=1*power(3,3-1) =1*3 =3
    return ans  ->  return 3
  ans=1*power(3,4-1) =1*3 =3
  return ans  ->  return 3

结果为:
  ans = 3
  return 3

这是因为在你编写 ans=ans*power(x,n-1) 时,ans 的值会在调用 power() 方法之前进行求值。

现在,如果你将其改为 ans=power(x,n-1)*ans,代码会按照以下方式执行:

ans = 1
power(3, 4):
  ans=power(x,n-1)*ans  ->  power(3,4-1)
  power(3, 3):
    ans=power(x,n-1)*ans  ->  power(3,3-1)
    power(3, 2):
      ans=power(x,n-1)*ans  ->  power(3,2-1)
      power(3, 1):
        return 3
      ans=power(3,2-1)*ans =3*1 =3
      return ans  ->  return 3
    ans=power(3,3-1)*ans =3*3 =9
    return ans  ->  return 9
  ans=power(3,4-1)*ans =9*9 =81
  return ans  ->  return 81

结果为:
  ans = 81
  return 81

这也是错误的。

基本上,在递归方法中不应使用字段,除非是在递归过程中不会改变的值,或者可能用作结果收集器。

英文:

The code doesn't work correctly because of order-of-evaluation.

Say you call power(3, 4).

ans = 1
power(3, 4):
  ans=ans*power(x,n-1)  ->  1*power(3,4-1)
  power(3, 3):
    ans=ans*power(x,n-1)  ->  1*power(3,3-1)
    power(3, 2):
      ans=ans*power(x,n-1)  ->  1*power(3,2-1)
      power(3, 1):
        return 3
      ans=1*power(3,2-1) =1*3 =3
      return ans  ->  return 3
    ans=1*power(3,3-1) =1*3 =3
    return ans  ->  return 3
  ans=1*power(3,4-1) =1*3 =3
  return ans  ->  return 3

Result is:
  ans = 3
  return 3

That is because, when you write ans=ans*power(x,n-1), the value of ans is evaluated before the power() method is invoked.

Now, if you had written ans=power(x,n-1)*ans instead, the code would flow like this instead:.

ans = 1
power(3, 4):
  ans=power(x,n-1)*ans  ->  power(3,4-1)
  power(3, 3):
    ans=power(x,n-1)*ans  ->  power(3,3-1)
    power(3, 2):
      ans=power(x,n-1)*ans  ->  power(3,2-1)
      power(3, 1):
        return 3
      ans=power(3,2-1)*ans =3*1 =3
      return ans  ->  return 3
    ans=power(3,3-1)*ans =3*3 =9
    return ans  ->  return 9
  ans=power(3,4-1)*ans =9*9 =81
  return ans  ->  return 81

Result is:
  ans = 81
  return 81

Which is also wrong.

Basically, you should not use fields in a recursive method, except for values that don't change during recursion, or potentially for a result collector.

huangapple
  • 本文由 发表于 2020年8月29日 17:28:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/63645440.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定