简体   繁体   中英

How does 3 digit number combinations 0-9 algorithm work?

#include<stdio.h>   
int main()
{
    int i, j, k;
    for (i = 0; i <= 7; i++)
    {
        for (j = i+1; j <= 8; j++)
        {
            for (k = j+1; k <= 9; k++)
            {
                printf("%d%d%d\n", i, j, k);
            }
        }
    }
}

I have this algorithm. It generates all 120 unique numbers. Maybe i am dumb, but i don't understand one simple thing. If I remove +1 from both inner loops variable initialization, I will receive 720 unique combinations. With this +1 I am receiving 120, that does not repeat. So it clears out numbers so there are no numbers like 517 and 715, for example. Can somebody explain how adding +1 to inner loops removes all different arrangements and only leaves one? Because there must be at least 6 unique sets of 120 numbers.

You just get one set of those numbers, those which have digits in ascending order. becasue you start with 012 and then start incrementing the last digit till 019 and continue with 023 . The +1 increases the next digit by one so it won't be the same. If you don't use it you would start at 000 and count up to 789 excluding all "nineties".

edit in regard to the comment:

In the generated numbers all your digits are in ascending order. So the last is always bigger than the other two. So if you start with 012 and start increasing you get all numbers that contain a 01 then all with 02 and so forth. Until you have all possibilities with 0 then you go to 123 this way there are no duplicates.

When you print the first set of digits, you have:

i j k --> i i+1 j+1 --> i i+1 i+2 --> 0 1 2,

and after the first completion of the k -loop you have:

i j k --> 0 1 9.

Then the j -loop is continued, with:

i j k --> 0 2 3.

If the initial values of the j - and k - loops were not incremented, then you would have:

i j k --> i i i --> 0 0 0
....
i j k --> 0 0 9
i j k --> 0 1 1,

and the sets would contain duplicate digits.

The algorithm gets all of the sets of three unique digits because it finds first all such sets that begin with 0 1 , and then all such sets that begin with 0 2 , ..., and then all such sets that begin with 1 2 , ..., and finally all such sets that begin with 7 8 , of which there is only one: 7 8 9 .

The limits placed on i , j , and k play a role in this. The last set will be 7 8 9 , so i is limited to a maximum value of 7, j is limited to 8, and k is limited to 9. When the i -loop is first continued:

i j k --> 0 8 9
i j k --> 1 2 3

There are no more unique sets that begin with 0 8 , and there are no unique sets that begin with 0 9 (we already have 0 1 9 , ..., 0 8 9 , justifying the limit that j <= 8 ), so now we have all unique sets that begin with 0 , and begin to find all unique sets that begin with 1 . The first of these is:

i j k --> i i+1 i+2 --> 1 2 3.

Systematic Counting

I think that it is a mistake to think of what is happening here as "getting rid of duplicates" or some kind of sorting. This is about systematic counting. We want to count the number of unique sets of three digits. The sets 1 2 3 , 3 2 1 , and 1 3 2 are equivalent, since they contain the same members, so we don't want to list all three, but just one of these. These sets of digits contain no duplicates, ie, 1 1 2 is not a set in this context. We are free to choose a convenient criterion for choosing which sets we will count, and we choose to count the (ordered) sets with the digits in ascending order. Note that we do not sort these, we simply count them.

The strategy employed is to list the combinations as if they were three-digit numbers, from smallest to largest. Naturally, the listing begins with the smallest possibility, 0 1 2 . Observe that the smallest such "number" that begins with the digit d is d d+1 d+2 , and that the largest such "number" is d 8 9 . The largest of all such "numbers" is 7 8 9 . These observations provide us with the limits for our loop conditions.

Think of this triple of digits as a counter. We can list all ascending three-digit "numbers" by stepping through the allowable combinations systematically. The reason for the +1 is that we have chosen to count the "numbers" with digits in ascending order. We could just as well have chosen to count the "numbers" with digits in descending order.

Come to think of it, this might be a good exercise for you: modify your algorithm to display the digits in descending order. This might help solidify your understanding.

I dug up a little bit more. And found next things:

We have 1000 3 digit numbers:

000-999

There are 720 possible 3 digit combinations, using the numbers 0-9:

10x9x8 = 720 combinations

There are 6 possible ways of arranging the 3 digits numbers:

3x2x1 = 6

This mean that there are duplicates in 720 numbers. For example, these set of numbers, from 720 combinations, are considered as duplicates:

157, 175, 517, 571, 715, 751

The goal is to get rid of duplicates with nested loops.

#include<stdio.h>
int main(void)
{
    int i, j, k;

    i = 0;
    while (i <= 9)
    {
        j = i + 1;
        while (j <= 9)
        {
            k = j + 1;
            while(k <= 9)
            {
                printf("%d%d%d\n", i, j, k);
                k++;
            }
            j++;
        }
        i++;
    }
}

If you replace +1 with 0, like this:

j = i + 1; with j = 0;

and

k = j + 1; k = 0;

You will generate all 1000 numbers.

If you additionally, put an if statement in the innermost loop:

while(k <= 9)
{
    if(i != j && i != k && j != k)
    {
        printf("%d%d%d\n", i, j, k);
    }
    k++;
}

Then you will receive 720 combinations.

But with these +1, we are getting descending order sort. Which goes like this:

012, 013, 014, 015, 016, 017, 018, 019
023, 024, 025, 026, 027, 028, 029
034, 035, 036, 037, 038, 039
045, 046, 047, 048, 049
056, 057, 058, 059
067, 068, 069
078, 079
089

And after inner loop ends it will go again starting with 123.

So, if I understand this correctly what this +1 does, is descend sort numbers.

Because we start from 0 we are generating 8 numbers in the first line. And with each loop cycle, we are receiving one number less wich each consecutive total loops pass.

And this gives us some math magic, that gets rid of all duplicates :)

Basically, because we are generating number and number +1 we will always receive unique numbers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM