1

there are many questions about how to convert recursive to non-recursive, and I also can convert some recursive programs to non-recursive form note: I use an generalized way (user defined Stack), because I think it is easy to understand, and I use Java, so can not use GOTO keyword.

Things don't always go so well, when I meet the Backtracking, I am stuck. for example, The subset problem. and my code is here: recursive call with loop

when i use user defined Stack to turn it to non-recursive form. I do not know how to deal with the loop (in the loop existing recursive call).

I googled found that there is many methods such as CPS. and I know there is an iterative template of subset problem. but i only want to use user defined Stack to solve.

Can someone provide some clues to turn this kind of recursive(recursive with loop) to non-recursive form(by using user defined Stack, not CPS etc..) ?

here is my code recursive to non-recusive(Inorder-Traversal), because of there is no loop with recursive call, so i can easily do it. also when recursive program with a return value, I can use a reference and pass it to the function as a param. from the code, I use the Stack to simulated the recursive call, and use "state" variable to the next call point(because java does not allow using GOTO).

The following is the information I have collected. It seems that all of them does not satisfy the question I mentioned(some use goto that java not allowed, some is very simple recursive means that no nested recursive call or recursive call with loop ).

1 Old Dominion University

2 codeproject

----------------------------------Split Line--------------------------------------

Thks u all. after when I post the question... It took me all night to figure it out. here is my solution: non-recursive subset problem solution, and the comment of the code is my idea.

To sum up. what i stuck before is how to deal with the foo-loop, actually, we can just simply ignore it. because we are using loop+stack, we can do a simple judgment on whether to meet the conditions.

Community
  • 1
  • 1
wannibar
  • 21
  • 3

2 Answers2

0

On your stack, have you thought about pushing i (the iteration variable)? By doing this, when you pop this value, you know at which iteration of the loop you were before you pushed on the stack and therefore, you can iterate to the next i and continue your algorithm.

gus3001
  • 851
  • 9
  • 19
  • yes, i push all the local var & param & return address to the stack. but yesterday i do not know how to split the for-loop from recursive call, now i know it. and i paste my solution in the question. – wannibar Jan 20 '18 at 02:37
0

Non-negative numbers only for simplicity. (Also no IntFunction.)

The power function, as defined here, is a very simple case.

int power(int x, int exponent) {
    if (exponent == 0) {
        return 1;
    } else if (exponent % 2 == 0) {
        int y = power(x, exponent /2);
        return y * y;
    } else {
        return x * power(x, exponent - 1);
    }
}

Now the stack is there to do in the reverse order to a partial result, what you did in recursion with the result.

int power(final int x, int exponent) {
    Stack<Function<Integer, Integer>> opStack = new Stack<>();
    final Function<Integer, Integer> square = n -> n * n;
    final Function<Integer, Integer> multiply = n -> x * n;
    while (exponent > 0) {
        if (exponent % 2 == 0) {
            exponent /= 2;
            opStack.push(square);
        } else {
            --exponent;
            opStack.push(multiply);
        }
    }
    int result = 1;
    while (!opStack.isEmpty()) {
        result = opStack.pop().apply(result);
    }
    return result;
}

An alternative would be to "encode" the two branches of if-else (odd/even exponent) by a boolean:

int power(final int x, int exponent) {
    BooleanStack stack = new BooleanStack<>();
    while (exponent > 0) {
        boolean even = exponent % 2 == 0;
        stack.push(even);
        if (even) {
            exponent /= 2;
        } else {
            --exponent;
        }
    }
    int result = 1;
    while (!stack.isEmpty()) {
        result *= stack.pop() ? result : x;
    }
    return result;
}

So one has to distinghuish:

  • what one does to prepare the recursive arguments
  • what one does with the partial results of the recursive calls
  • how one can merge/handle several recursive calls in the function
  • exploit nice things, like x being a final constant

Not difficult, puzzling maybe, so have fun.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • from my point, the power function is different from "recursive with loop". the power function i can easily turn into non-recursive. and do not use lambda expression. 1. add a param(Represents a return value) to the function , then the power become a void function. 2. split into different stage, 3. push/pop No brain operation hhh... Any way thank for you answer. – wannibar Jan 20 '18 at 02:30