Click here to Skip to main content
14,391,319 members

Nested Loop Alternative

Rate this:
3.71 (7 votes)
Please Sign up or sign in to vote.
3.71 (7 votes)
27 Nov 2019CPOL
A time-saver algorithm to do a number generator tool.

(You need Visual Studio to compile the project.)

Introduction

Nested Loop, a big word for a limited function, for each new slots, you need to add another child/parent loop, manually.

That's a tough job for sure, not ideal if we want to generate a lot of slot, like for number generator function.

Background

First of all, the first time I encounter this algorithm of nested loop, was with my wish (2010) to be able to generate all texts possible, since I realized that books were just a series of characters, put side by side, that form words then phrases.

So here's my first application that needed the uses of nested loop:

void    main()
{
    char array[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    for (int one = 0; one < 26; one++)
    {
        for (int two = 0; two < 26; two++)
        {
            for (int three = 0; three < 26; three++)
            {
                for (int four = 0; four < 26; four++)
                {
                    printf("%c%c%c%c\n", array[one], array[two], array[three], array[four]);
                }
            }
        }
    }
}

But here's my problem,

As said at top, if I want do generate like 10 or 100 character slot, I need to type it by hands,

And I don't have time to do that, maybe use macro, but I am not that advanced into macro use, and C# doesn't allow macro.

So, I was looking for a dynamic way to create nested loops, but I failed or didn't understand how to apply the algorithm found on the internet.

But a few days ago, I found a way, it was to disassemble the algorithm behind nested loop and build another one on it.

Here's a single loop:

for (int i = 0; i < 10; i++)
{
    MessageBox.Show(i.ToString());
}

That display:

0 1 2 3 4 5 6 7 8 9 10

Here's a nested loop:

for (int i = 0; i < 2; i++)
{
    for (int ii = 0; ii < 10; ii++)
    {
        MessageBox.Show(i.ToString() + ii.ToString());
    }
}

That display:

00 01 02 03 04 05 06 06 08 09 10 11 12 13 14 15 16 17 18 19

And here's the unroll of the nested loop:

Boolean IsFinish = false;
Int32[] Index    = new Int32[2];

while (!IsFinish)
{
    MessageBox.Show(Index[1].ToString() + Index[0].ToString());

    Index[0]++;

    if (Index[0] == 10)
    {
        Index[1]++;
        Index[0] = 0;
    }

    if (Index[1] == 2)
    {
        IsFinish = true;
    }
}

that displays:

00 01 02 03 04 05 06 06 08 09 10 11 12 13 14 15 16 17 18 19

Same as above.

To explain this nested loop unrolling, the loop for() is basically a loop with parameters, so, a loop inside another loop, is just a loop with 2 parameters that communicate between them to know when to be incremented, it's what the if() does.

And when we have all parameters reach their limits, we are leaving the infinite loop by checking the parent loop parameter of the nested loop.

The loop's parameters are stored in Index[].

So now that we have the basic knowledge of the logic behind nested loop, let's add more child/parent loop to test this algo with complex code:

for (int i1 = 0; i1 < 2; i1++)
{
    for (int i2 = 0; i2 < 10; i2++)
    {
        for (int i3 = 0; i3 < 10; i3++)
        {
            for (int i4 = 0; i4 < 10; i4++)
            {
                for (int i5 = 0; i5 < 10; i5++)
                {
                    for (int i6 = 0; i6 < 10; i6++)
                    {
                        MessageBox.Show(i1.ToString() + i2.ToString() + i3.ToString() +
                                        i4.ToString() + i5.ToString() + i6.ToString());
                    }
                }
            }
        }
    }
}

This loop display 0 to 199_999.

And if we are applying the previous logic to this new nested loop, it should give this:

Boolean IsFinish = false;
Int32[] Index    = new Int32[6];

while (!IsFinish)
{
    MessageBox.Show(Index[5].ToString() + Index[4].ToString() + Index[3].ToString() +
                    Index[2].ToString() + Index[1].ToString() + Index[0].ToString());

    Index[0]++;

    if (Index[0] == 10)
    {
        Index[1]++;
        Index[0] = 0;
    }

    if (Index[1] == 10)
    {
        Index[2]++;
        Index[1] = 0;
    }

    if (Index[2] == 10)
    {
        Index[3]++;
        Index[2] = 0;
    }

    if (Index[3] == 10)
    {
        Index[4]++;
        Index[3] = 0;
    }

    if (Index[4] == 10)
    {
        Index[5]++;
        Index[4] = 0;
    }

    if (Index[5] == 2)
    {
        IsFinish = true;
    }
}

 

This loop display 0 to 199_999.

Perfect, now we have successfully disassembled the algorithm behind nested loop.

Now let's dig in the next step, since we are still in need to manually write the parameters' incrementation, it's not finished yet.

If we take a closer look at the if blocks, we can find a redundant signature, it looks like the code inside if condition doesn't change so much, just the index of the array that follows a logical series.

Let's translate into a code:

Boolean IsFinish = false;
Int32[] Index    = new Int32[6];

while (!IsFinish)
{
    MessageBox.Show(Index[5].ToString() + Index[4].ToString() + Index[3].ToString() +
                    Index[2].ToString() + Index[1].ToString() + Index[0].ToString());

    Index[0]++;

    for (int i = 0; i < 6; i++)
    {
        if (Index[i] == 10 && i != 5)
        {
            Index[i + 1]++;
            Index[i] = 0;
        }

        if (Index[6 - 1] == 2)
        {
            IsFinish = true;
        }
    }
}

(For simplification and understanding of the algorithm, I will now upscale 2 to 10, it will just increase the count up to 999_999.)

(i != 5 is there to avoid index being outside array's bounds.)

Good, now let's create some variables since we have redundant values: 6 and 10.

Boolean IsFinish      = false;
Int32   MemberNumber  = 10;
Int32   IndexNumber   = 6;
Int32[] Index         = new Int32[IndexNumber];

while (!IsFinish)
{
    MessageBox.Show(Index[5].ToString() + Index[4].ToString() + Index[3].ToString() +
                    Index[2].ToString() + Index[1].ToString() + Index[0].ToString());

    Index[0]++;

    for (int i = 0; i < IndexNumber; i++)
    {
        if (Index[IndexNumber - 1] == MembersNumber)
        {
            IsFinish = true;
        }
        else if (Index[i] == MembersNumber)
        {
            Index[i + 1]++;
            Index[i] = 0;
        }
    }
}

To make it short, MembersNumber mean how many entities are being processed by the number generator and IndexNumber means how many slots are being used to store the previous entities.

Great, we have reached the end of the number generator algorithm explanation.

Points of Interest

I never liked algorithm studying, but the way in which I learnt with this project has been really fun and interesting.

History

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

wqaxs36
France France
No Biography provided

Comments and Discussions

 
QuestionHere's another way to do it Pin
Pete Lomax Member 106645054-Dec-19 3:32
professionalPete Lomax Member 106645054-Dec-19 3:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Tip/Trick
Posted 27 Nov 2019

Tagged as

Stats

2K views
37 downloads
1 bookmarked