【问题标题】:C : 0 & 1 combinations using recursionC:使用递归的 0 和 1 组合
【发布时间】:2012-11-01 07:52:49
【问题描述】:

我想根据变量编号(数字)使用 c 递归地列出 o 和 1 的组合

我想要的输出是

000
001
010
011
100
101
110
111

我尝试了很多算法,最后一个是:

void permute(unsigned number)    {

    if(number == 0) {
        printf("\n");
        return;
    }

    permute(number - 1);
        printf("0");
    permute(number - 1);
        printf("1");


}   //permute ends here


void permuteN(unsigned number) {

    unsigned i;

    for(i = 0; i < number + 1; i++){
        permute(i);
    }
}   //permuteN ends here

我认为它给了我答案但没有排序,因为我不知道该放在哪里\n;

需要你的帮助!

【问题讨论】:

  • 这些不是排列,这些是组合
  • @MatteoItalia 不,根据维基百科和我的记忆,当订单不重要时,您需要组合。在这种情况下,明确的顺序很重要(001010100 不同)
  • @madth3 排列是您对集合中的值重新排序的地方。组合是您在集合中获取任何值的地方。如果您置换001,则唯一的选项是001010100
  • @paddy 我没有说这些是排列,我只是指出它们也不是组合:en.wikipedia.org/wiki/Combination。在某些圈子里,我看到这些被称为“重复排列”,但那是另一回事了。

标签: c recursion combinations truthtable


【解决方案1】:

如果您确实只是在寻找 10 的组合,我建议您数数并以二进制形式列出。

以二进制形式获取数字0...7 并仅获取最后 3 位(可能应用掩码),最终得到与您指定的相同的集合:

000
001
...
...
111

n位组合,需要0..2^n - 1


基于this answer,适用于一个特定情况的 3 位 (感谢@ChrisLutz 和@dirkgently)

#include <stdio.h>
int main(){
int numdigits = 3, j;
    for(j=1; j<8; j++)
        printbits(j);
}

void printbits(unsigned char v) {
  int i;
  for(i = 2; i >= 0; i--) putchar('0' + ((v >> i) & 1));
  printf("\n");
}

输出:

000
001
010
011
100
101
110
111

【讨论】:

  • 我知道这个想法,但不是我想要的
【解决方案2】:

您实际上所做的只是将数字转换为二进制...。一个简单的循环无需任何库调用即可完成此操作(printf 除外)...

const unsigned int numbits = 3;
unsigned int bit;

for( bit = 1U << (numbits-1); bit != 0; bit >>= 1 ) {
    printf( number&bit ? "1" : "0" );
}
printf( "\n" );

已编辑,因为您似乎想要递归。您需要有一些方法来指定您需要多少位。您需要将其传递到您的递归例程中:

#include <stdio.h>

void permute(unsigned number, unsigned bits)
{
    if( bits == 0 ) return;
    permute(number / 2, bits-1);
    printf( "%d", number % 2 );
}   //permute ends here


void permuteN(unsigned number, unsigned bits ) {

    unsigned i;

    for(i = 0; i < number + 1; i++){
        permute(i, bits);
        printf("\n");
    }
}   //permuteN ends here

int main(void)
{
    permuteN(7, 3);
    return 0;   
}

要按您需要的顺序获得输出,您不知道何时编写换行符。所以在这种情况下,你以后再写。

【讨论】:

    【解决方案3】:

    @paddy 有一个很好的答案;只是增加了一点(正如你对我的评论的回复,我的强硬 - 比赛有点晚了)。这依赖于 pow() ,(以及 log10 打印的一些细节),尽管如此;如果使用 gcc 编译 -lm:

    base在这里可能有点令人困惑 - 但你猜你明白了。

    gcc -Wall -Wextra -pedantic -o combo combo.c -lm

    /* gcc - Wall -Wextra -pedantic  -o combo combo.c -lm */
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    static void prnt_combo(unsigned number, unsigned bits, int base)
    {
        if (!bits)
            return;
        prnt_combo(number / base, --bits, base);
        printf("%d", number % base);
    }
    
    
    void prnt_combos(int bits, int base)
    {
        int i;
        int n = pow(base, bits);
        int wp = log10(n) + 1;
    
        fprintf(stderr,
            "Printing all combinations of 0 to %d by width of %d numbers. "
            "Total %d.\n",
            base - 1, bits, n
        );
    
        for (i = 0; i < n; i++) {
            fprintf(stderr, "%*d : ", wp, i);
            prnt_combo(i, bits, base);
            printf("\n");
        }
    }
    
    
    /* Usage: ./combo [<bits> [<base>]]
     *        Defaults to ./combo 3 2
     * */
    int main(int argc, char *argv[])
    {
        int bits = argc > 1 ? strtol(argv[1], NULL, 10) : 3;
        int base = argc > 2 ? strtol(argv[2], NULL, 10) : 2;
    
        prnt_combos(bits, base);
        return 0;
    }
    

    示例:

    $ ./combo 4 2
    Printing all combinations of 0 to 1 by width of 4 numbers. Total 16.
     0 : 0000
     1 : 0001
     2 : 0010
     3 : 0011
     4 : 0100
     5 : 0101
     6 : 0110
     7 : 0111
     8 : 1000
     9 : 1001
    10 : 1010
    11 : 1011
    12 : 1100
    13 : 1101
    14 : 1110
    15 : 1111
    

    干净输出:

    $ ./combo 3 2 >&2-
    000
    001
    010
    011
    100
    101
    110
    111
    

    您可能想添加如下内容:

    if (base > 10)
        printf("%x", number % base);
    else
        printf("%d", number % base);
    

    prnt_combo()。这样你就得到了,即 2 16:

        0 : 00
        1 : 01
        2 : 02
        3 : 03
        4 : 04
      ...
      250 : fa
      251 : fb
      252 : fc
      253 : fd
      254 : fe
      255 : ff
    

    【讨论】:

    • 比你给我另一个好主意
    猜你喜欢
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多