简体   繁体   English

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

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

I have an assignment in which I am not allowed to use " [] ", and to do it only with pointers. 我有一个作业,不允许我使用“ [] ”,而只能使用指针。
So far my code works alright, but I am facing a problem while I print all possible combinations of 6 of K numbers. 到目前为止,我的代码可以正常工作,但是当我打印K的6个数字的所有可能组合时遇到了问题。
Here is my code: 这是我的代码:

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

And let's say that the user enters 6 numbers, the print of combinations is correct(1|2|3|4|5|6). 假设用户输入了6个数字,则组合的打印正确(1 | 2 | 3 | 4 | 5 | 6)。
But if user chooses anything else, for example 7 numbers, the results are: 但是,如果用户选择其他任何内容(例如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

I am stuck and I can't figure out what's my wrong, any hint please? 我被困住了,无法弄清楚我怎么了,请问有什么提示吗?
I am 95% sure that the mistake is at printf, but I tried several changes and none worked. 我有95%的肯定是在printf上出错了,但是我尝试了几次更改,但均无效果。
Sorry for my english, 对不起我的英语不好,
Cheers, 干杯,
pronoobgr pronoobgr

I found my problem, when user was entering numbers, I had my code like this: 我发现了问题,当用户输入数字时,我的代码是这样的:

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

and at printing the combinations the "i" was set to 1. So I changed the "i" at the "Choosing numbers", and set it i=0: 然后在打印组合时将“ i”设置为1。因此我在“选择数字”处更改了“ i”,并将其设置为i = 0:

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

and now everything works! 现在一切正常! Anyway, thanks for your time! 无论如何,感谢您的宝贵时间!

Your problem is that you are using as many loops as many numbers you have, but the number of numbers is dynamic if you mean to work with permutations. 您的问题是您使用的循环数越多,但是如果要使用置换,数字的数目就是动态的。 I will give you the idea only, as this is obviously homework: 我只会给你这个主意,因为这显然是家庭作业:

  • use a stack to store your current state 使用堆栈存储您的当前状态
  • the stack should have the size of K and should have values of -1 堆栈的大小应为K,值应为-1
  • you should operate with the indexes, rather than the values, only use the values when you output the solution in the form of *(ar + index) 您应该使用索引而不是值来操作,仅当以*(ar + index)的形式输出解决方案时才使用值
  • given depth < K, find the first possible index which is greater than the index at depth. 给定深度<K,找到第一个可能的索引,该索引大于深度索引。 If there is such an index, then assign it to the given position and increase depth. 如果存在这样的索引,则将其分配给给定位置并增加深度。 Otherwise decrease depth 否则减少深度
  • if depth reaches K, then you have a solution, print it, or do whatever you need to do with it 如果深度达到K,那么您有解决方案,可以打印出来,或者做任何需要做的事情
  • if depth reaches -1, then the algorithm successfully finished 如果深度达到-1,则算法成功完成

This is not a good design to print combinations. 这不是打印组合的好设计。 your programs complexity is O(k^n) whereas the same problem can be solved with O(2^n) complexity by using a two-way recursion function. 您的程序复杂度为O(k ^ n),而通过使用双向递归函数可以用O(2 ^ n)复杂度解决相同的问题。 Moreover, rather than using 6 nested loops you can simply use a multi recursion loop. 而且,与其使用6个嵌套循环,不如直接使用多递归循环。 Multi recursion loop will help you control the depth of nesting of loops. 多重递归循环将帮助您控制循环嵌套的深度。 and that way your program will be able to solve combination problems like nCk directly (rather than nC6, wherein you are using a constant value 6 for k). 这样,您的程序就可以直接解决nCk之类的组合问题(而不是nC6,因为您在k中使用常数6)。

Anyway, you can read about above-mentioned stuff in free time. 无论如何,您可以在空闲时间阅读上述内容。 Now, let me come back to your original problem. 现在,让我回到您的原始问题。 The issue is in your nested loops. 问题出在您的嵌套循环中。 I correct your loops in the below code snippet. 我在下面的代码片段中更正了您的循环。

1. you should not decrement 'a' at every nested loop (eg a-5, a-4 is wrong) 1.不应在每个嵌套循环中递减“ a”(例如a-5,a-4错误)
2. start 'i' from value '0' 2.从值“ 0”开始“ i”
3. don't use '<=' operater in the loop. 3.不要在循环中使用“ <=”运算符。 rather use '<' operator. 而是使用“ <”运算符。
4. printf printing wrong values, correct values are => *(ar+i), *(ar+j), *(ar+k), *(ar+I), *(ar+J), *(ar+K). 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