Javascript 递归函数-为什么不是无限循环?

Javascript 递归函数-为什么不是无限循环?,javascript,Javascript,因此,这显然是一段有效的代码,但是如果index参数不是0的话,我不知道如何完成对power的第二次调用 function power(base, exponent) { if (exponent == 0) return 1; else return base * power(base, exponent - 1); } From:因为第二次调用将继续以指数形式调用较小的数字,直到它达到0,然后返回1,并回滚聚合结果 我认为您必须阅读一些关于递归的内容:) 下面是一个

因此,这显然是一段有效的代码,但是如果
index
参数不是
0
的话,我不知道如何完成对
power
的第二次调用

function power(base, exponent) {
  if (exponent == 0)
    return 1;
  else
    return base * power(base, exponent - 1);
}

From:

因为第二次调用将继续以指数形式调用较小的数字,直到它达到0,然后返回1,并回滚聚合结果

我认为您必须阅读一些关于递归的内容:)

下面是一个简单的例子来说明它的外观:

power(2,2) 
 power(2,1) 
    power(2,0) 
       return 1 
    return 2*1 = 2 
 return 2*2 = 4 
从中提取和修改

尝试此页面(对我不起作用,这是一个旧页面,需要java,我的机器上没有安装它…)


编辑:
这让我很困扰,因为我找不到任何简单的例子,所以这里有一个快速的控制台程序,可以帮助您想象这是如何工作的:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SO_Console
{
    class Program
    {
        static void Main(string[] args)
        {
            int base_value = 0;
            int exponent = 0;
            string[] parts = new string[2];
            int result = 0;
            Console.Out.WriteLine("Please enter the Power to calculate in this format: x^y "
            + Environment.NewLine + "(where x is the base (int) and y is the exponent (int)."
            + Environment.NewLine);

            var temp = Console.ReadLine();
            if (!string.IsNullOrWhiteSpace(temp))
            {

                parts = temp.Split('^');
                if (parts.Length != 2)
                InvalidInput();
            }
            else
            InvalidInput();


            if (Int32.TryParse(parts[0], out base_value) && Int32.TryParse(parts[1], out exponent))
            result = Power(base_value, exponent, "");
            else
            InvalidInput();

            Console.Out.WriteLine(Environment.NewLine + "Final result = {0}", result);


            Console.Out.WriteLine(Environment.NewLine + "Hit any key to quit.");
            Console.Read();

        }

        /// <summary>
        /// Recursive call to calculate Power x^y
        /// </summary>
        /// <param name="base_value">The base</param>
        /// <param name="exponent">The exponent</param>
        /// <param name="padding">Padding, for output.</param>
        /// <returns></returns>
        private static int Power(int base_value, int exponent, string padding)
        {
            Console.Out.WriteLine(string.Format("{2}Power called with: {0}^{1}", base_value, exponent, padding));
            Thread.Sleep(750);

            if (exponent == 0)
            {
                Console.Out.WriteLine("{0}{1}Base case reached, returning 1.{0}", Environment.NewLine ,padding);
                return 1;
            }
            else
            {
                var return_value = base_value * Power(base_value, exponent - 1, padding + "  ");
                Console.Out.WriteLine("{0}Going back in the recursion, returning {1}.", padding, return_value);
                Thread.Sleep(750);
                return return_value;
            }
        }

        /// <summary>
        /// Inform user about bad input and quit.
        /// </summary>
        private static void InvalidInput()
        {
            Console.Out.WriteLine("Invalid input.");
            return;
        }
    }
}
使用系统;
使用System.Collections.Generic;
利用制度全球化;
使用System.Linq;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
名称空间SO_控制台
{
班级计划
{
静态void Main(字符串[]参数)
{
int base_值=0;
int指数=0;
字符串[]部分=新字符串[2];
int结果=0;
Console.Out.WriteLine(“请输入此格式的计算功率:x^y”
+Environment.NewLine+“(其中x是基(int),y是指数(int)。”
+环境(新线),;
var temp=Console.ReadLine();
如果(!string.IsNullOrWhiteSpace(temp))
{
零件=临时拆分(“^”);
如果(parts.Length!=2)
无效输入();
}
其他的
无效输入();
if(Int32.TryParse(部分[0],out base_值)和&Int32.TryParse(部分[1],out指数))
结果=幂(基值,指数“”);
其他的
无效输入();
Console.Out.WriteLine(Environment.NewLine+“Final result={0}”,result);
Console.Out.WriteLine(Environment.NewLine+“按任意键退出”);
Console.Read();
}
/// 
///计算幂x^y的递归调用
/// 
///基地
///指数
///填充,用于输出。
/// 
私有静态整数幂(整数基值、整数指数、字符串填充)
{
Console.Out.WriteLine(string.Format(“{2}幂调用时使用:{0}^{1}”,基值,指数,填充));
睡眠(750);
如果(指数=0)
{
WriteLine(“{0}{1}到达基本大小写,返回1.{0}”,Environment.NewLine,padding);
返回1;
}
其他的
{
var返回值=基值*幂(基值,指数-1,填充+“”);
WriteLine(“{0}返回递归,返回{1}.”,填充,返回_值);
睡眠(750);
返回_值;
}
}
/// 
///通知用户输入错误并退出。
/// 
私有静态void InvalidInput()
{
Console.Out.WriteLine(“无效输入”);
返回;
}
}
}
您只需粘贴并运行它,您的结果就会显示出来:

编辑2:

我写了一篇关于这一点的文章,详细解释了为什么会发生什么,为什么会发生在哪里。欢迎您在这里查看:。

注意xn=x×xn-1和x0=1。这就是代码正确的原因。

请尝试一个例子。这里是2到3的幂

power(2,3) = 2 * (power(2,2) = 2 * (power(2,1) = 2 * (power(2,0) = 1)))
因此:


递归仅在具有时终止。在求幂的情况下,边的情况是:

n0=1

它的意思是“任何提升到0的幂的数字都是1”

求幂的一般情况是:

nx=n×nx-1

在Haskell等数学语言中,幂运算的定义如下:

n ^ 0 = 1
n ^ x = n * n ^ (x - 1)
有趣的是,如果给这个函数一个负整数,那么边缘条件将永远不会执行,它将运行到一个无限循环中,最终以堆栈溢出结束

但是,由于我们只对整数(0和正整数)使用此函数,因此您永远不会遇到无限循环

然而,如果使用足够大的指数,仍然会遇到堆栈溢出,因为计算机只有这么多空间来存储中间结果


在大多数JavaScript浏览器中,您可以计算
2^2^14
。但是,如果您试图计算
2^2^15
,则会出现堆栈溢出:

请在问题本身中包含有效代码,并且出于您的至爱,不要使用代码的屏幕截图。编辑注意:这不是建议重新编译的正确方法vised snippet。将其作为答案的一部分发布。当您使用除指数的正整数以外的任何其他值调用它时,它是一个无限循环(或者更好:堆栈溢出)。
n ^ 0 = 1
n ^ x = n * n ^ (x - 1)