簡體   English   中英

3位數字組合0-9算法如何工作?

[英]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);
            }
        }
    }
}

我有這個算法。 它生成所有120個唯一編號。 也許我很笨,但是我不明白一件簡單的事。 如果我從兩個內部循環變量初始化中刪除+1,我將收到720個唯一組合。 有了這個+1,我將收到120,不再重復。 因此,它會清除數字,因此不會出現例如517和715這樣的數字。 有人可以解釋一下如何向內部循環中添加+1來刪除所有不同的排列並只留下一個嗎? 因為必須至少有6組唯一的120個數字。

您只獲得一組數字,那些數字以升序排列。 因為您從012開始,然后開始將最后一位數字遞增到019然后繼續從023 +1將下一位數字增加一位,因此不會相同。 如果您不使用它,則從000開始,直到789為止(不包括所有“ 90”)。

編輯有關評論:

在生成的數字中,所有數字均按升序排列。 因此,最后一個總是大於其他兩個。 因此,如果您從012開始並開始增加,則會得到所有包含01數字,然后全部包含02 ,依此類推。 直到您將所有可能性都設置為0為止,然后您便以這種方式轉到123 ,沒有重復項。

當您打印第一組數字時,您具有:

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

在第一個完成k循環之后,您將擁有:

i j k --> 0 1 9.

然后,繼續執行j -loop:

i j k --> 0 2 3.

如果jk循環的初始值未增加,則您將具有:

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 -loop時:

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

沒有更多的以0 8開頭的唯一集合,也沒有以0 9開頭的唯一集合(我們已經有了0 1 9 ,..., 0 8 9 ,證明了j <= 8的極限),所以現在我們擁有以0開頭的所有唯一集合,並開始查找以1開頭的所有唯一集合。 第一個是:

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

系統計數

我認為將這里發生的事情視為“擺脫重復”或某種排序是錯誤的。 這是關於系統計數。 我們要計算三位數的唯一集合的數量。 集合1 2 3 3 2 11 3 2是等效的,因為它們包含相同的成員,因此我們不想列出所有三個,而僅列出其中之一。 這些數字集不包含重復項,即1 1 2在此上下文中不是集合。 我們可以自由選擇一個方便的標准來選擇要計數的集合,並且我們選擇按數字升序對(有序)集合進行計數。 注意,我們不對它們進行排序,我們只是對它們進行計數。

所采用的策略是列出組合,就好像它們是三位數字一樣,從最小到最大。 自然地,列表從最小的可能性0 1 2 請注意,以數字d開頭的最小“數字”是d d+1 d+2 ,而最大的此類“數字”是d 8 9 所有這些“數字”中最大的是7 8 9 這些觀察為我們提供了循環條件的極限。

將此三位數視為計數器。 通過系統地瀏覽允許的組合,我們可以列出所有升序的三位數“數字”。 +1的原因是我們選擇按數字升序對“數字”進行計數。 我們還可以選擇按降序對“數字”進行計數。

想一想,這可能對您來說是一個好練習:修改算法以按降序顯示數字。 這可能有助於鞏固您的理解。

我多挖了一點。 並發現接下來的事情:

我們有1000個3位數字:

000-999

共有720種可能的3位數組合,使用數字0-9:

10x9x8 = 720個組合

排列3位數字的方法有6種:

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,所以我們將始終收到唯一的數字。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM