Frustrating recursive functions in JS [duplicate]

人盡茶涼 提交于 2021-01-21 06:16:05

问题


I've been wracking my brain on this all day, and I still don't get it. Could someone please explain to me, how on earth does this function work?!?!?!

function findSolution(target) {
  function find(current, history) {
    if (current == target) {
      return history;
    } else if (current > target) {
      return null;
    } else {
      return find(current + 5, `(${history} + 5)`) ||
        find(current * 3, `(${history} * 3)`);
    }
  }
  return find(1, "1");
}

console.log(findSolution(24));
// → (((1 * 3) + 5) * 3)

How does it not keep going back and forth calling on itself in an infinite loop?


回答1:


Basically, that test:

if (current == target) {
    return history;
}

tests if the solution has been found, and then returns that solution

while that test:

if (current > target) {
    return null;
}

finds out that no solution can be found, and then returns null.

For example, if you try findSolution(10), you will get null.

Else, if we are not in one of those recursion ending conditions, the code will continue to search and to build the solution string.

So, this code will try to build every possible combination of "+5" and "*3" until it produces either the given number, or null if the combination gives a greater number.




回答2:


You could add a console.log in the first line of the recursive function and watch what is going on.

I changed the function to a version without else parts, because all if statements return.

The functionality stays.

In the function find, there are two exit conditions and one hidden:

  1. Check for target value, (ok, this is obvious)

  2. Check if the current value is greater than the target value, then exit with null or any other falsy value, because the return value is used in the next hidden check.

  3. Check with logical OR ||, if

    find(current + 5, `(${history} + 5)`)
    

    returns a truthy value and if not return the result of the other function call

    find(current * 3, `(${history} * 3)`)
    

    with either a truty or falsy value (without check).

Together it takes one at start and tries to add 5 or multiply by 3 until the wanted value is reached.

function findSolution(target) {

    function find(current, history) {
        console.log(current, history);
    
        if (current == target) {
            return history;
        }
        if (current > target) {
            return null;
        }
        return find(current + 5, `(${history} + 5)`) || find(current * 3, `(${history} * 3)`);
    }

    return find(1, "1");
}

console.log(findSolution(24)); //  (((1 * 3) + 5) * 3)
.as-console-wrapper { max-height: 100% !important; top: 0; }


来源:https://stackoverflow.com/questions/48686988/frustrating-recursive-functions-in-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!