user-0 提问: 任意长度数组的全组合

回复:
user: user-1
content: 这是不重复全排列，不是组合，组合是顺序无关的。

user: user-0
content: #include <stdio.h> #include <stdlib.h>  void   Comb(char array[], int n);  int main(void) {     char   array[10] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};      Comb(array, 3);     return 0; /*************************************** 输出结果： A B C AB AC BC ABC ***************************************/ }   /* 全组合 */ /* 打印任意长度数组的全组合 */ /* 二进制转化法，模拟手动按顺序枚举所有组合 */ void Comb(char array[], int n) {     int    i, j, m, flag, cnt;     int*   buf;      buf = (int*) calloc(n, sizeof(int));      for (m = 1; m <= n; m++) {         /* 初始化 */         for (i = 0; i < n; i++)             buf[i] = i < m ? 1 : 0;          while (1) {             /* 输出一个组合 */             for (i = 0; i < n; i++)                 if (buf[i]) printf("%c", array[i]);             printf("\n");              /* 检查是否已经列出所有的组合，如果后m位都为1，说明已列出所有组合 */             flag = 1;             for (i = n - m; i < n; i++) {                 if (buf[i] == 0) {                     flag = 0;                     break;                 }             }             if (flag) break;              /* 将右边第1个“10”组合变成“01” */             for (i = n - 1; i > 0; i--) {                 if (buf[i] == 0 && buf[i - 1] == 1) {                     buf[i] = 1;                     buf[i - 1] = 0;                     break;                 }             }              /* 如果最后一位为1，则将右端所有连续的1移动到第i位之后，其它位设为0 */             if (buf[n - 1]) {                 for (j = n - 1, cnt = 0; j > i; j--) {                     if (buf[j] == 0)                         break;                     cnt++;                 }                 for (j = i + 1; j < n; j++) {                     if (j < i + 1 + cnt)                         buf[j] = 1;                     else                         buf[j] = 0;                 }             }         }     } }

user: user-0
content: 引用 6 楼 vilnies 的回复:补上代码void   print(char array[], int print_len , char * last) { 	for( int i = 0 ; i < (print_len - 1 ) ; i++) 		printf("%c" , array[i]); 	printf("%c\n", *last); }  void   Comb(char array[], int n) {	 	for( int i = 0 ; i < n ; i++ ) 	{		  		for( int last =  i ; last < n ; last ++) 		{ 			print(array , i + 1 ,&array[last] ); 		} 	} } int main(void) { 	char   array[] = {'A', 'B', 'C', 'D', 'E'}; 	Comb(array, 5); 	return 0; }  可能我给的示例误导了你的算法，我想要的是全组合，你的运行结果长度为2以上时，全是以A开头的 我想要的是，AB AC AD AE BC BD BE CD CE DE ABC ABD...  不过我改了一下最初的方法，达到了要求，下面上代码

user: user-2
content: 补上代码void   print(char array[], int print_len , char * last) { 	for( int i = 0 ; i < (print_len - 1 ) ; i++) 		printf("%c" , array[i]); 	printf("%c\n", *last); }  void   Comb(char array[], int n) {	 	for( int i = 0 ; i < n ; i++ ) 	{		  		for( int last =  i ; last < n ; last ++) 		{ 			print(array , i + 1 ,&array[last] ); 		} 	} } int main(void) { 	char   array[] = {'A', 'B', 'C', 'D', 'E'}; 	Comb(array, 5); 	return 0; }

user: user-2
content: 分析变化因素有2: 1.打印长度.规律是递增,初始值为1,最大值为n.优先度最高 2.打印串最后一个char.规律也是递增,且初始值为原数组中该位置的值,最大值为原数组的最后一个.  另外,其余的位置的值和原数组顺序一致.  所以两重循环就可以了.

user: user-3
content: 循环2^n次，写个getnext函数判断下个值是多少，比如E下一个是AB等等

user: user-4
content: 此贴应该对LZ颇有参考价值。 http://bbs.csdn.net/topics/390631458

user: user-5
content: 用递归可以了

user: user-4
content: 思路有4，供参考： 1. 将每个单独结果存起来，然后排序，再输出：耗费空间大，只能使用小批量组合；    （小变种：仍然是将结果存起来，不过是组合所有结果，将每个结果按字母规律存      储在存储空间的适合偏移位置，相信更难控制） 2. 每个结果存起来，然后使用可以定位光标位置的输出（如conio）； 3. 调整枚举算法，让其输出按特定规律。