C:使用递归的 0 和 1 组合
Posted
技术标签:
【中文标题】C:使用递归的 0 和 1 组合【英文标题】:C : 0 & 1 combinations using recursion 【发布时间】: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 不,根据***和我的记忆,当订单不重要时,您需要组合。在这种情况下,明确的顺序很重要(001
与 010
或 100
不同)
其实是三元笛卡尔积:en.wikipedia.org/wiki/Cartesian_product#n-ary_product
@madth3 排列是您对集合中的值重新排序的地方。组合是您在集合中获取任何值的地方。如果您置换001
,则唯一的选项是001
、010
和100
。
@paddy 我没有说这些是排列,我只是指出它们也不是组合:en.wikipedia.org/wiki/Combination。在某些圈子里,我看到这些被称为“重复排列”,但那是另一回事了。
【参考方案1】:
如果您确实只是在寻找 1
和 0
的组合,我建议您数数并以二进制形式列出。
以二进制形式获取数字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
【讨论】:
比你给我另一个好主意以上是关于C:使用递归的 0 和 1 组合的主要内容,如果未能解决你的问题,请参考以下文章
vb组合数c(n,m) 递归求法,要用function函数。