繁体   English   中英

生成K个数字中6个的所有可能组合

[英]Generate All Possible Combinations of 6 of K numbers

我有一个作业,不允许我使用“ [] ”,而只能使用指针。
到目前为止,我的代码可以正常工作,但是当我打印K的6个数字的所有可能组合时遇到了问题。
这是我的代码:

    # include <stdio.h>
    int main() {
    system("chcp 1253");

    int a, i, j, temp, *ar, k, I, J, K;
    printf("Numbers must be 6 or 49.\n"); /*User can enter 6-49 numbers*/
    scanf("%d",&a);
    while(a<6 || a>49) {
            printf("Wrong, choose again: \n");
            scanf("%d", &a);
        } 

    ar = (int*) malloc(a*sizeof(int)); /*Creating array*/

    system("cls");
    printf("Choosing numbers*/
    for (i=0; i<a; i++) {
        scanf("%d", ar+i);
        while (*(ar+i)<1 || *(ar+i)>49) { /*Numbers must be greater than 1 and less than 49*/
        printf("Wrong number, choose again: \n");
        scanf("%d", ar+i);
        }
    }

    for (i=0; i<a; i++) { /*Sorting array*/
        for (j=i+1; j<a; j++) {
            if (*(ar+i) > *(ar+j)) {
                temp = *(ar+i);
                *(ar+i) = *(ar+j);
                *(ar+j) = temp;
            }
        }
    }

    printf("\n\n"); /*Printing all possible 6 combinations of K numbers*/
    for(i=1; i<=a-5; i++) {
        for(j=i+1; j<=a-4; j++) {
            for(k=j+1; k<=a-3; k++) {
                for(I=k+1; I<=a-2; I++) {
                    for(J=I+1; J<=a-1; J++) {
                        for(K=J+1; K<=a; K++) {
                            printf("%d|%d|%d|%d|%d|%d|\n", *(ar), *(ar+i), *(ar+j), *(ar+k), *(ar+I), *(ar+J));
                            }
                        }
                    }
                }
            }
        }


    free(ar);
    return 0; 
}

假设用户输入了6个数字,则组合的打印正确(1 | 2 | 3 | 4 | 5 | 6)。
但是,如果用户选择其他任何内容(例如7个数字),则结果为:

1|2|3|4|5|6
1|2|3|4|5|6
1|2|3|4|5|7
1|2|3|4|6|7
1|2|3|5|6|7
1|2|4|5|6|7
1|3|4|5|6|7

我被困住了,无法弄清楚我怎么了,请问有什么提示吗?
我有95%的肯定是在printf上出错了,但是我尝试了几次更改,但均无效果。
对不起我的英语不好,
干杯,
pronoobgr

我发现了问题,当用户输入数字时,我的代码是这样的:

printf("Choosing numbers*/
    for (i=0; i<a; i++) {
        scanf("%d", ar+i);

然后在打印组合时将“ i”设置为1。因此我在“选择数字”处更改了“ i”,并将其设置为i = 0:

printf("Choosing numbers*/
        for (i=1; i<a; i++) {
            scanf("%d", ar+i);

现在一切正常! 无论如何,感谢您的宝贵时间!

您的问题是您使用的循环数越多,但是如果要使用置换,数字的数目就是动态的。 我只会给你这个主意,因为这显然是家庭作业:

  • 使用堆栈存储您的当前状态
  • 堆栈的大小应为K,值应为-1
  • 您应该使用索引而不是值来操作,仅当以*(ar + index)的形式输出解决方案时才使用值
  • 给定深度<K,找到第一个可能的索引,该索引大于深度索引。 如果存在这样的索引,则将其分配给给定位置并增加深度。 否则减少深度
  • 如果深度达到K,那么您有解决方案,可以打印出来,或者做任何需要做的事情
  • 如果深度达到-1,则算法成功完成

这不是打印组合的好设计。 您的程序复杂度为O(k ^ n),而通过使用双向递归函数可以用O(2 ^ n)复杂度解决相同的问题。 而且,与其使用6个嵌套循环,不如直接使用多递归循环。 多重递归循环将帮助您控制循环嵌套的深度。 这样,您的程序就可以直接解决nCk之类的组合问题(而不是nC6,因为您在k中使用常数6)。

无论如何,您可以在空闲时间阅读上述内容。 现在,让我回到您的原始问题。 问题出在您的嵌套循环中。 我在下面的代码片段中更正了您的循环。

1.不应在每个嵌套循环中递减“ a”(例如a-5,a-4错误)
2.从值“ 0”开始“ i”
3.不要在循环中使用“ <=”运算符。 而是使用“ <”运算符。
4. printf打印错误的值,正确的值是=> *(ar + i),*(ar + j),*(ar + k),*(ar + I),*(ar + J),*(ar + K)。

  for(i=0; i<a; i++) {
      for(j=i+1; j<a; j++) {
          for(k=j+1; k<a; k++) {
              for(I=k+1; I<a; I++) {
                  for(J=I+1; J<a; J++) {
                      for(K=J+1; K<a; K++) {
                          printf("%d|%d|%d|%d|%d|%d|\n", *(ar+i), *(ar+j), *(ar+k), *(ar+I), *(ar+J), *(ar+K));
                        }
                    }
                }
            }
        }
    }

暂无
暂无

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

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