Jun Hyuk Han
Jun Hyuk Han

Reputation: 23

Unintended behavior in c++ when passing in an incremented integer to a recursive function

The code itself accepts N and M from standard input and prints M-length combinations from 1 to N.

#include <iostream>

void print(int *arr, int size)
{
        for (int i=0; i<size; i++)
                std::cout << arr[i] << " ";
        std::cout << "\n";
}

bool is_found(int *arr, int size, int num)
{
        for (int i=0; i<size; i++)
        {
                if (num == arr[i])
                        return true;
        }
        return false;
}

void recurse(int *arr, int n, int m, int cur)
{
        if (cur >= m)
                print(arr, m);
        else
        {
                for (int i=1; i<=n; i++)
                {
                        if (is_found(arr, cur + 1, i))
                                continue;
                        arr[cur] = i;
                        recurse(arr, n, m, cur + 1);
                }
        }
}

int main()
{
        int *arr;
        int n;
        int m;
        int temp;

        std::cin >> n >> m;
        arr = new int[n];
        for (int i=0; i<n; i++)
                arr[i] = 0;
        recurse(arr, n, m, 0);
}

Eg.

input: 4 4
output: 
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 2 3
1 4 3 2
2 1 4 3
2 3 1 4
2 3 4 1
2 4 1 3
2 4 3 1
3 1 2 4
3 1 4 2
3 2 1 4
3 2 4 1
3 4 1 2
3 4 2 1
4 1 3 2
4 2 1 3
4 2 3 1
4 3 1 2
4 3 2 1

The code above works as intended. However, in the recurse function, changing this part of the code results in unexpected behavior.

    arr[cur] = i;
    recurse(arr, n, m, cur + 1);
void recurse(int *arr, int n, int m, int cur)
{
        if (cur >= m)
                print(arr, m);
        else
        {
                for (int i=1; i<=n; i++)
                {
                        if (is_found(arr, cur + 1, i))
                                continue;
                        // option 1 (original, works)
                        arr[cur] = i;
                        recurse(arr, n, m, cur + 1);
                        // option 2 (doesn't work)
                        arr[cur++] = i;
                        recurse(arr, n, m, cur);
                        // option 3 (doesn't work)
                        arr[cur] = i;
                        cur = cur + 1;
                        recurse(arr, n, m, cur);

This is the output when using option 2 and option 3

input: 4 4
output:
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2

My question is, aren't the three options written above equivalent? I don't understand why option 1 works as intended and options 2 and 3 don't. Why does passing in the value cur + 1 to the recursive function work, but changing the value of cur before passing, doesn't?

My best guess is that it has something to do with recursion and using the same array for the recursive call, or perhaps the problem is from a completely different part of the code. But I really have no idea why this is happening. Any help is greatly appreciated! Thank you in advance!

Upvotes: 0

Views: 87

Answers (1)

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122830

This:

         // option 1 (original, works)
         arr[cur] = i;
         recurse(arr, n, m, cur + 1);

Does not modify cur. The loop continues with the next loop and the value of cur is the same in the next iteration. On the other hand, this

         // option 2 (doesn't work)
         arr[cur++] = i;
         recurse(arr, n, m, cur);
         // option 3 (doesn't work)
         arr[cur] = i;
         cur = cur + 1;

Both modify cur and the value wont be the same in the next iteration. I suppose the confusion is caused by recursion, but consider the same without recursion:

            int cur = 0;
            for (int i=1; i<=n; i++)
            {
                    arr[cur] = i;
            }

vs

            int cur = 0;
            for (int i=1; i<=n; i++)
            {
                    cur = cur + 1;
                    arr[cur] = i;
            }

Would you expect this two to be identical?

Upvotes: 1

Related Questions