Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/409.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 无overun的递归_Javascript_Recursion - Fatal编程技术网

Javascript 无overun的递归

Javascript 无overun的递归,javascript,recursion,Javascript,Recursion,我一直在寻找递归的真实例子。记住,编程向导,我是艺术家,在Photoshop脚本(scriptus操作方式)中,它通常用于在所有层和子层上循环 我正在编写一个(简单的)递归脚本来解决一个四位数的组合锁。你知道,从1开始,然后尝试2,然后3等等,直到找到解决方案。为了简化示例中的内容,第二个数字是正确的,因此我们知道不必更改它。初始状态也是从零开始的,但我们知道在最终解中没有零 尝试必须与解决方案相匹配,并且加起来等于10,以便 解决问题 这看起来有点像stoppid,但我想把解决方案分为两部

我一直在寻找递归的真实例子。记住,编程向导,我是艺术家,在Photoshop脚本(scriptus操作方式)中,它通常用于在所有层和子层上循环

我正在编写一个(简单的)递归脚本来解决一个四位数的组合锁。你知道,从1开始,然后尝试2,然后3等等,直到找到解决方案。为了简化示例中的内容,第二个数字是正确的,因此我们知道不必更改它。初始状态也是从零开始的,但我们知道在最终解中没有零

  • 尝试必须与解决方案相匹配,并且加起来等于10,以便 解决问题
这看起来有点像stoppid,但我想把解决方案分为两部分,主要是因为我可以应用我学到的知识,编写一个蛮力suduko解算器。但你必须爬才能滑冰

var puzzle = [0,2,0,0]; // source
var solution = [1,2,3,4];
var s = superCopy(puzzle); // working array


drawPuzzle(s);
solvePuzzle(s, puzzle);

var total = checkTotal(s, solution);
var solution = checkSolution(s, solution);


function checkTotal(arr, source)
{
  var c = 0;

  // count the total
  for (var i = 0; i < arr.length; i++)
  {
    c += arr[i];
  }
  if (c == 10)
  {
    alert("Total OK")
    return true;
  }
}

function checkSolution(arr, source)
{
  // check the solution
  for (var i in arr)
  {
    if (arr[i] != source[i]) return false
    return true;
  }
}

function solvePuzzle(arr, source)
{
  for (var i = 0; i < arr.length; i++)
  {
    // check the source
    var sourceCell = source[i];
    //alert("checking source " + sourceCell)
    //if it's a zero we can change it
    if (arr[i] == 0) 
    {
      cell = arr[i];

      cell+=1;
      if (cell > 4) cell = 0;
      arr[i] = cell;
    }
  }

  // check the solution
  for (var i in arr)
  {
    // overflow time!
    if (arr[i] != source[i]) solvePuzzle(arr, source)
    else
    {
      alert("All done!")
    }
  }
}

function drawPuzzle(arr)
{
  var p = "";
  var c = 0;
  for (var i = 0; i < arr.length; i++)
  {
    if (arr[i] == 0) p += "-" 
    else p += arr[i];
  c+=1;
  }
  alert(p);
}

function superCopy(arr)
{
  // returns a true copy of an array
  tempArr = new Array();
  for (var i = 0; i < arr.length; i++)
  {
    if (arr[i] == 0) tempArr[i] = 1 // changed, thanks Nostradamnit!
    else tempArr[i] = arr[i]
  }
  return tempArr
}
var-puzzle=[0,2,0,0];//来源
var溶液=[1,2,3,4];
var s=超级副本(拼图);//工作阵列
抽签游戏;;
解谜;
var total=检查总计(s,溶液);
var溶液=检查溶液(s,溶液);
功能检查总计(arr,源)
{
var c=0;
//数一数总数
对于(变量i=0;i4)单元格=0;
arr[i]=单元;
}
}
//检查解决方案
用于(arr中的var i)
{
//溢出时间!
if(arr[i]!=source[i])解算拼图(arr,source)
其他的
{
警报(“全部完成!”)
}
}
}
函数(arr)
{
var p=“”;
var c=0;
对于(变量i=0;i
脚本不完整。这就是我到目前为止所知道的,它会出现溢出错误。注意:solvePuzzle和checkTotal函数没有被调用,因为我意识到solvePuzzle需要调用自己,并制定解决方案……这是当我遇到溢出问题并感到有点困惑时


我意识到这种类型的问题与“修复我的代码”的风险非常接近,所以我准备为此悬赏。谢谢。

乍一看,您的超级副本功能似乎有缺陷。创建一个空数组,然后将其0索引(不存在)与输入数组进行比较。这就是“溢出”的原因吗?

问题似乎是您在同一次迭代中多次调用
solvePuzzle(arr,source)

  for (var i in arr)
  {
    // overflow time!
    if (arr[i] != source[i]) solvePuzzle(arr, source)
    else
    {
      alert("All done!")
    }
  }
因此,迭代数组中的每个项,如果它不等于
项,则再次调用
solvePuzzle
。但是,如果您有多个不匹配的项,
solvePuzzle
将在同一数组中多次调用。对于每次呼叫,它都会被再次调用多次。因此,函数调用呈指数增长,最终导致堆栈溢出

您可能打算做的是:

  var areArraysEqual = true;
  for (var i in arr)
  {
    if (arr[i] != source[i]) {
        areArraysEqual = false;
        break;
    }
  }

  if (areArraysEqual) {
      alert("All done!");
  } else { 
      solvePuzzle(arr, source);
  }

我还没有看过你的解决方案,但我确实为自己编写了一个递归解决方案来解决这个问题。也许它可以作为一个指导方针

var solution = [1,2,3,4];

function checkSolution(arr) {
  return solution.every(function(item, index){ return item === arr[index]; });
}

function increment(arr) {
  for (var i=0; arr[i] === 9; i++) {
    arr[i] = 0;
  }
  arr[i]++;
  return arr;
}

function solvePuzzle(arr) {  
  if (isNaN(arr[arr.length-1])) {
      return null;
  }
  if (checkSolution(arr)) {
    return arr;
  }

  return solvePuzzle(increment(arr));
}



var solution = solvePuzzle([1,1,1,1]);
console.log(solution); // [1,2,3,4]

您的代码有几个问题。首先,checkSolution函数在匹配的第一个数字处停止。您可能希望它在返回true之前检查每个数字,因此您应该将
返回true
移到for循环之外。只有当所有的数字都匹配时,它才能到达那里

另一个缺陷是超焦函数,正如Nostrandamnit指出的那样,它有一个有缺陷的条件

您的下一个问题是solvePuzzle,这里有:

if (arr[i] == 0) 
{
  cell = arr[i];

  cell+=1;
  if (cell > 4) cell = 0;
  arr[i] = cell;
}
问题是,因为
arr[i]
是0,而您只添加1,所以单元格永远不会是4。所以你的if永远不会开火。这就是无限循环的位置:它只会以1递增0的值,所以在所有0变为1之后,它就再也不会前进了,并且您会不断检查“1111”是否是解决方案

现在溢出:您不应该为每个单元格调用solvePuzzle,这是指数增长的:

for (var i in arr)
{
  // overflow time!
  if (arr[i] != source[i]) solvePuzzle(arr, source)
  else
  {
    alert("All done!")
  }
}
而且,您永远不会再次检查结果,因此循环永远不会结束。您可能希望将此更改为:

if(checkTotal(arr) && checkSolution(arr, source))
{
  alert("All done!");
  return;
}
solvePuzzle(arr, source);

作为旁注(不是引起bug的原因):您的checkTotal函数没有使用源参数,因此您可能可以省略它。此外,solvePuzzle中还有一个叫做cell的流氓变量,在本例中这不是什么大问题,但最好将var放在它前面,这样它就不会变成全局变量。此外,还有一个从未使用过的sourceCell变量。

可能有点离题,但我认为我创建了最简单的递归示例


哎呀!我错过了。我现在已经修复了超级副本。不,错误发生在solvePuzzle(s,puzzle)上,我认为您将进入一个无限循环,因为solvePuzzle中的第一个for不起任何作用。第一个for中的if检查arr[i]==0,但superCopy函数确保所有等于0的索引都更改为1,因此此条件永远不存在,然后继续在未更改的数组上递归,继续不将其更改为无穷大。重新审视一下你的逻辑;)
var str = "9785";
function rec(a, b)
{
    var c=0;
    if(b==-1)
        return "";
       if(a!=str.charAt(b))
           return rec(a+1, b);
        else
        {
            return rec(0,b-1)+""+a;
        }
}
var ans = rec(0,str.length-1)