简体   繁体   English

生成所有可能的 3 位数字组合而不重复

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

I'm trying to write a program that prints all possible combinations of three digits.我正在尝试编写一个程序来打印所有可能的三位数组合。 And there is the constraint that:并且存在以下约束:

  1. The three digits must be different三位数必须不同
  2. 012, 120, 102, 021, 201, and 210 are considered the same combination of the three digits 0, 1 and 2 012、120、102、021、201、210被认为是0、1、2这三个数字的相同组合
  3. Print only the smallest combination of three digits只打印三个数字的最小组合

The expected output is as follows预期的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 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

I'm trying to implement in C but the algorithm or any language implementation will suffice.我正在尝试在 C 中实现,但算法或任何语言实现就足够了。

Here is what I've done so far but it's inacurrate.这是我到目前为止所做的,但它是不准确的。

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

Here is a fairly compact snippet of code for giving the smallest unique three-digit number.这是一个相当紧凑的代码片段,用于给出最小的唯一三位数字。

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

You can give that a try.你可以试试看。

Here's some annotated code that might improve the outcome.这是一些可能会改善结果的带注释的代码。

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

and

// 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 = ", ";

Notice that 'j', 'k' and 'l' have no meaning to this problem.请注意,“j”、“k”和“l”对这个问题没有意义 Easy to putchar() the numbers in reverse order without noticing...很容易在不注意的情况下以相反的顺序putchar()数字...

Of course, if this is not a homework assignment (Prof wouldn't believe you wrote this)...当然,如果这不是家庭作业(教授不会相信你写的)......

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

And, to use the equivalence of array addressing and pointers .并且,使用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;
}

Inspired by comment by @Chux, here is the same thing expanded to printing 4 digits.受@Chux 评论的启发,这里是扩展为打印 4 位数字的相同内容。 Comparison will show the few trivial alterations needed.比较将显示所需的一些微不足道的更改。

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

You can do:你可以做:

#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: 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,

Explanation:解释:

  • In the program - h , t and u represents digit at hundredth location, digit at tenth location and digit at unit location respectively in a three digit number.在程序中 - htu分别以三位数字表示百位数字、第十位数字和单位位数字。

  • Initialised h with '0' , t with '1' and u with '2' because 012 is the smallest three digit number without any of the digits being repeated.'0'初始化h ,用'1'初始化t和用'2'初始化u因为012是最小的三位数字,没有任何数字重复。

  • while loop condition ((h <= '7') || (t <= '8') || (u <= '9')) because 789 is biggest three digit number which follow constraint of - smallest combination of three digits without any of the digits being repeated. while循环条件((h <= '7') || (t <= '8') || (u <= '9'))因为789是遵循以下约束的最大三位数 - 三位数的最小组合没有任何数字重复。 Any other combination of 7 , 8 and 9 will be bigger than 789 and any three digit number bigger than 789 will violat one of the given constraints. 78的任何其他组合9将大于789 ,并且任何大于789的三位数字都将违反给定的约束之一。

  • If you find it difficult to understand the expression with ternary operation如果你觉得难以理解三元运算的表达式

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

    then here is simplified version using if else :那么这里是使用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 } }

Here is how I went about my solution:以下是我的解决方案:

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

The variables in order of a, b, & c;变量按 a、b、& c 的顺序排列; a for 1st digit, b for 2nd and c for 3rd. a 代表第一位,b 代表第二位,c 代表第三位。

The use of b = a + 1 & c = b + 1 was an idea given to me by user @chux - Reinstate Monica in another post that linked me to this one that involved two integers instead of 3 (For two digits, the code only needs to be slightly tweaked to cater for 2 integers).使用 b = a + 1 & c = b + 1 是用户@chux 给我的一个想法 - 在另一篇文章中恢复莫妮卡,该文章将我链接到这个涉及两个整数而不是 3 的帖子(对于两位数,代码只需要稍微调整以适应 2 个整数)。

Moving on.继续。

The if statements: if 语句:

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

and

if (a + b + c < 24)

will filter out the duplicates and ensure that the comma and space are not applied to the last combo of integers respectively (ie 789, which sum up to give 24).将过滤掉重复项并确保逗号和空格不会分别应用于整数的最后一个组合(即 789,总和为 24)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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