3位数组合0-9算法如何工作?

时间:2016-11-04 13:25:41

标签: c algorithm math

#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);
            }
        }
    }
}

我有这个算法。它生成所有120个唯一编号。也许我很蠢,但我不明白一件简单的事情。 如果我从内部循环变量初始化中删除+1,我将收到720个唯一组合。有了这个+1,我收到120,这不重复。因此它清除了数字,因此没有像517和715这样的数字。 有人可以解释如何在内部循环中添加+1会删除所有不同的安排而只留下一个吗?因为必须至少有6个独特的120个数字集。

3 个答案:

答案 0 :(得分:1)

您只需获得一组这些数字,即按升序排列的数字。因为您从012开始,然后开始递增最后一个数字直到019并继续023+1将下一个数字增加1,因此它不会相同。如果你不使用它,你将从000开始,并计算到789,不包括所有&#34;九十年代&#34;。

编辑评论:

在生成的数字中,所有数字都按升序排列。所以最后一个总是比其他两个更大。 因此,如果您从012开始并开始增加,则会获得包含01的所有数字,然后全部包含02,依此类推。直到你有0的所有可能性,然后你去123这样没有重复。

答案 1 :(得分:1)

当您打印第一组数字时,您有:

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

在第一次完成k - 循环之后,你有:

i j k --> 0 1 9.

然后继续j - 循环,其中包含:

i j k --> 0 2 3.

如果j - 和k - 循环的初始值没有增加,那么你会得到:

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

并且这些集合将包含重复的数字。

该算法获取所有三个唯一数字的集合,因为它首先找到以0 1开头的所有此类集合,然后找到以0 2,...开头的所有此类集合,然后所有此类集以1 2,...开头,最后所有此类集以7 8开头,其中只有一个7 8 9

ijk的限制在此中起作用。最后一组将为7 8 9,因此i的最大值限制为7,j限制为8,k限制为9. i {1}} - 循环首先继续:

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

没有更多以0 8开头的唯一集合,并且没有以0 9开头的唯一集合(我们已经有0 1 9,...,{{1} },证明0 8 9)的限制,现在我们拥有以j <= 8开头的所有唯一集合,并开始查找以0开头的所有唯一集合。第一个是:

1

系统计数

我认为想到这里发生的事情是错误的,因为&#34;摆脱重复&#34;或某种排序。这是关于系统计数。我们想要计算三位数的唯一集合数。集i j k --> i i+1 i+2 --> 1 2 3. 1 2 33 2 1是相同的,因为它们包含相同的成员,因此我们不想列出所有三个,而只是列出其中一个。这些数字集不包含重复项,即1 3 2不是此上下文中的集合。我们可以自由选择一个方便的标准来选择我们将计算的集合,并且我们选择按数字升序计算(有序)集合。请注意,我们不对它们进行排序,我们只是计算它们。

采用的策略是将组合列为三位数字,从最小到最大。当然,列表从可能性最小的1 1 2开始。观察最小的这样的数字&#34;从数字0 1 2开始的是d,而最大的数字是{#1}数字&#34;是d d+1 d+2。所有这些&#34;中最大的数字&#34;是d 8 9。这些观察为我们提供了循环条件的限制。

将这三位数视为一个计数器。我们可以列出所有提升的三位数&#34;数字&#34;通过系统地逐步通过允许的组合。 7 8 9的原因是我们选择计算&#34;数字&#34;数字按升序排列。我们也可以选择计算&#34;数字&#34;数字按降序排列。

想想看,这对你来说可能是一个很好的练习:修改你的算法以按降序显示数字。这可能有助于巩固您的理解。

答案 2 :(得分:0)

我挖了一点。并找到了下一步:

我们有1000个3位数字:

  

000-999

有720种可能的3位数组合,使用数字0-9:

  

10x9x8 = 720种组合

有6种可能的方法来安排3位数字:

  

3x2x1 = 6

这意味着720个数字中有重复数据。例如,720组合的这些数字组被视为重复:

  

157,175,517,571,715,751

目标是摆脱嵌套循环的重复。

#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++;
    }
}

如果您将+1替换为0,请执行以下操作:

j = i + 1; with j = 0;

k = j + 1; k = 0;

您将生成所有1000个数字。

如果另外,在最里面的循环中放置一个if语句:

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

然后你会收到720种组合。

但是这些+1,我们正在降序排序。 这是这样的:

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

在内循环结束后,它将再次以123开始。

所以,如果我正确地理解了这个+1的作用,那就是降序排序。

因为我们从0开始,所以在第一行产生8个数字。并且对于每个循环周期,我们每个连续的总循环都会接收一个数字。

这给了我们一些数学魔法,摆脱了所有重复:)

基本上,因为我们正在生成数字和数字+1,我们将始终收到唯一的数字。