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

时间:2018-01-16 18:24:43

标签: c numbers

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

    # 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

3 个答案:

答案 0 :(得分:0)

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

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

现在一切正常!无论如何,谢谢你的时间!

答案 1 :(得分:0)

您的问题是您使用的循环数与您拥有的数量一样多,但如果您要使用排列,则数字的数量是动态的。我只会给你一个想法,因为这显然是家庭作业:

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

答案 2 :(得分:0)

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

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

1.你不应该在每个嵌套循环中减少'a'(例如a-5,a-4是错误的)
2.从值'0'开始'i' 3.不要在循环中使用'&lt; ='operater。而是使用'&lt;'运营商。
4. printf打印错误的值,正确的值是=&gt; *(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));
                        }
                    }
                }
            }
        }
    }