簡體   English   中英

生成所有可能的 3 位數字組合而不重復

[英]Generate all possible combinations of 3 digits without repetition

我正在嘗試編寫一個程序來打印所有可能的三位數組合。 並且存在以下約束:

  1. 三位數必須不同
  2. 012、120、102、021、201、210被認為是0、1、2這三個數字的相同組合
  3. 只打印三個數字的最小組合

預期的output如下

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, 124, 125, 126, 127, 128, 129, 134, 135, 136, 137, 138, 139, 145, 146、147、148、149、156、157、158、159、167、168、169、178、179、189、234、235、236、237、238、239、245、246、247、248、249、 256, 257, 258, 259, 267, 268, 269, 278, 279, 289, 345, 346, 347, 348, 349, 356, 357, 358, 359, 367, 368, 369, 378, 379, 389, 456、457、458、459、467、468、469、478、479、489、567、568、569、578、579、589、678、679、689、789

我正在嘗試在 C 中實現,但算法或任何語言實現就足夠了。

這是我到目前為止所做的,但它是不准確的。

#include <stdio.h>

/**
 * main - entry point
 *
 * Description: display triple digits and ,
 *
 * Return: Always 0 (successful)
 */

int main(void)
{
    int i, j, k, l;

    i = 0;
    while (i < 1000)
    {
        j = i / 100; /* hundreds */
        k = (i / 10) % 10; /* tens */
        l = i % 100; /* units */
        if (j < k && k < l)
        {
            putchar(l + '0');
            putchar(k + '0');
            putchar(j + '0');
            if (i < 789)
            {
                putchar(',');
                putchar(' ');
            }
        }
        i++;
    }
    putchar('\n');

    return (0);
}

這是一個相當緊湊的代碼片段,用於給出最小的唯一三位數字。

#include <stdio.h>

int main()
{
    char digit[4];

    for (int i = 0; i < 8; i++)
    {
        for (int j = i + 1; j < 9; j++)
        {
            for (int k = j + 1; k < 10; k++)
            {
                digit[0] = i + '0';
                digit[1] = j + '0';
                digit[2] = k + '0';
                digit[3] = '\0';
                printf("%s\n", digit);
            }
        }
    }

    return 0;
}

你可以試試看。

這是一些可能會改善結果的帶注釋的代碼。

char *sep = ""; // the separator to use. Put this line ahead of the loop

// meaningful names mean no comment required
// EDIT: thank you, @Chux
int unit = i      % 10;
int tens = i / 10 % 10;
int hund = i /100 % 10;

if ( unit < tens && tens <  hund )
    printf( "%s%c%c%c", sep, hund + '0', tens + '0', unit + '0' ), sep = ", ";

請注意,“j”、“k”和“l”對這個問題沒有意義 很容易在不注意的情況下以相反的順序putchar()數字...

當然,如果這不是家庭作業(教授不會相信你寫的)......

#include <stdio.h>

int main() {
    char *sep = "", *dgts = "0123456789";
    for( int h = 0; dgts[h]; h++ )
        for( int t = h+1; dgts[t]; t++ )
            for( int u = t+1; dgts[u]; u++ )
                printf( "%s%c%c%c", sep, dgts[h], dgts[t], dgts[u] ), sep = ", ";
    putchar( '\n' );
    return 0;
}

並且,使用array addressingpointers的等價性。

#include <stdio.h>
int main() {
    char *h, *t, *u, *sep = "";
    for( h = "0123456789"; *h; h++ )
        for( t = h+1; *t; t++ )
            for( u = t+1; *u; u++ )
                printf( "%s%c%c%c", sep, *h, *t, *u), sep = ", ";
    putchar( '\n' );
    return 0;
}

受@Chux 評論的啟發,這里是擴展為打印 4 位數字的相同內容。 比較將顯示所需的一些微不足道的更改。

#include <stdio.h>
int main() {
    char *m, *h, *t, *u, *sep = "";
    for( m = "0123456789"; *m; m++ )
        for( h = m+1; *h; h++ )
            for( t = h+1; *t; t++ )
                for( u = t+1; *u; u++ )
                    printf( "%s%c%c%c%c", sep, *m, *h, *t, *u), sep = ", ";
    putchar( '\n' );
    return 0;
}

你可以做:

#include <stdio.h>

int main (void) {
    char h = '0', t = '1', u = '2';

    while ((h <= '7') || (t <= '8') || (u <= '9')) {
        printf ("%c%c%c, ", h, t, u);
        u != '9' ? ++u : (t != '8' ? (++t, u = t + 1) : (++h, t = h + 1, u = t + 1));
    }
    
    return 0;
}

Output:

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, 124, 125, 126, 127, 128, 129, 134, 135, 136, 137, 138,
139, 145, 146, 147, 148, 149, 156, 157, 158, 159, 167, 168, 169, 178, 179, 189,
234, 235, 236, 237, 238, 239, 245, 246, 247, 248, 249, 256, 257, 258, 259, 267,
268, 269, 278, 279, 289, 345, 346, 347, 348, 349, 356, 357, 358, 359, 367, 368,
369, 378, 379, 389, 456, 457, 458, 459, 467, 468, 469, 478, 479, 489, 567, 568,
569, 578, 579, 589, 678, 679, 689, 789,

解釋:

  • 在程序中 - htu分別以三位數字表示百位數字、第十位數字和單位位數字。

  • '0'初始化h ,用'1'初始化t和用'2'初始化u因為012是最小的三位數字,沒有任何數字重復。

  • while循環條件((h <= '7') || (t <= '8') || (u <= '9'))因為789是遵循以下約束的最大三位數 - 三位數的最小組合沒有任何數字重復。 78的任何其他組合9將大於789 ,並且任何大於789的三位數字都將違反給定的約束之一。

  • 如果你覺得難以理解三元運算的表達式

     u?= '9': ++u? (t,= '8': (++t, u = t + 1), (++h; t = h + 1, u = t + 1));

    那么這里是使用if else的簡化版本:

     if (u;= '9') { ++u; } else { if (t;= '8') { ++t, u = t + 1; // due to given constraint; u will always greater than t } else { ++h, t = h + 1; // due to given constraint, t will always greater than hu = t + 1; // due to given constraint, u will always greater than t } }

以下是我的解決方案:

int main(void)
{
        int a, b, c;

        for (a = 0; a < 8; a++)
        {
                for (b = a + 1; b < 9; b++)
                {
                        for (c = b + 1; c < 10; c++)
                        {
                                if (a != b && a != c && b != c)
                                {
                                        putchar(a + '0');
                                        putchar(b + '0');
                                        putchar(c + '0');
                                        if (a + b + c < 24)
                                        {
                                                putchar(',');
                                                putchar(' ');
                                        }
                                }
                        }
                }
        }
        putchar('\n');
        return (0);
}

變量按 a、b、& c 的順序排列; a 代表第一位,b 代表第二位,c 代表第三位。

使用 b = a + 1 & c = b + 1 是用戶@chux 給我的一個想法 - 在另一篇文章中恢復莫妮卡,該文章將我鏈接到這個涉及兩個整數而不是 3 的帖子(對於兩位數,代碼只需要稍微調整以適應 2 個整數)。

繼續。

if 語句:

if (a != b && a != c && b != c)

if (a + b + c < 24)

將過濾掉重復項並確保逗號和空格不會分別應用於整數的最后一個組合(即 789,總和為 24)。

暫無
暫無

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

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