user-0 提问: 关于排列组合的一个小算法

回复:
user: user-1
content: “给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

user: user-1
content: //qplw.cpp #include <stdio.h> #include <string.h> #include <stdlib.h> int v=0; int w=0; int m;//记录字符串长度 int n;//记录字符串中的字符种类数 char map[256];//记录是哪几种字符 int count[256];//记录每种字符有多少个 int stack[1000];//递归用的栈，并记录当前生成的排列 void Make_Map(char *str) {//统计字符串的相关信息     int s[256];     int i;     memset(s,0,sizeof(s));     memset(count,0,sizeof(count));     m=strlen(str);     if (w<1 || m<w) w=m;     while(*str) {         s[*str]++;         str++;     }     n=0;     for (i=0;i<256;i++)         if (s[i]) {             map[n]=i;             count[n]=s[i];             n++;         } } void Find(int depth) {//递归式回溯法生成全排列     if (depth==w) {         int i;         for (i=0;i<depth;i++) putchar(map[stack[i]]);         putchar('\n');     } else {         int i;         if (v && depth>0) {             for (i=0;i<depth;i++) putchar(map[stack[i]]);             putchar('\n');         }         for (i=0;i<n;i++)             if (count[i]) {                 stack[depth]=i;                 count[i]--;                 Find(depth+1);                 count[i]++;             }     } } void main(int argc,char**argv) {     if (argc<2) {         printf("%s 要产生全排列的字符串 [限定长度|-1]\n",argv[0]);         return;     }     if (argc>=3) w=atoi(argv[2]);     if (-1==w) v=1;     Make_Map(argv[1]);     Find(0); } //C:\test>qplw //qplw 要产生全排列的字符串 [限定长度|-1] // //C:\test>qplw 123 //123 //132 //213 //231 //312 //321 // //C:\test>qplw 123 2 //12 //13 //21 //23 //31 //32 // //C:\test>qplw 122333 3 //122 //123 //132 //133 //212 //213 //221 //223 //231 //232 //233 //312 //313 //321 //322 //323 //331 //332 //333 // //C:\test>qplw 123 -1 //1 //12 //123 //13 //132 //2 //21 //213 //23 //231 //3 //31 //312 //32 //321 //

user: user-2
content: 引用 1 楼 caozhy 的回复:int n = 3; for (int i = 0; i < (1 << n); i++) {      int t = i;     for (int j = 0; j < n; j++)     {         printf("%c ", t % 2 == 0 ? '#' : '*');         t /= 2;     }     printf("\n"); } 写完自己的发现和你的思路是一样的，在实现上还是相差有点距离啊，要向大牛学习啊

user: user-2
content: 你将#看成0，*看成1，输入一个数N,公有2^N种情况，相当于就是用N位的2进制数从0到2^N-1表示, # include <stdio.h>  void numConvert(int (*p)[10], int n, int data);  int main() { 	int i, j, col, row = 1; 	int arr[1024][10];	//假设输入的 N <= 10 	printf("input number N:"); 	scanf("%d", &col);  	j = col; 	while (j > 0) 	{ 		row *= 2; 		j--; 	} 	for (i = 0; i < row; i++) 	{ 		numConvert(arr + i, col, i);	//进制转换 	}  	for (i = 0; i < row; i++) 	{ 		for (j = 0; j < col; j++) 		{ 			if (arr[i][j] == 0) 				printf("#"); 			else 				printf("*"); 		} 		printf("\n"); 	}  	return 0; }  void numConvert(int (*p)[10], int n, int data) { 	int i;  	for (i = n - 1; i >= 0; i--) 	{ 		p[0][i] = data % 2; 		data = data / 2;  	} }

user: user-3
content: 为了能够让用户输入N，承接1楼的实现：   #include <stdio.h> #include <stdlib.h> #include <ctype.h>  #define MAX_INPUT_LENGTH 10  int is_numeric(const char *p) {     if (*p)     {         char c;         while ((c=*p++))         {             if (!isdigit(c))                 return 0;         }         return 1;     }     return 0; }  int main() {     char str[MAX_INPUT_LENGTH];     printf ("Enter N: ");     scanf("%s", str);     if (0 == is_numeric(str))     {         printf("Please enter an integer!\n");         return 1;     }     int n = atoi(str);      for (int i = 0; i < (1 << n); i++)     {         int t = i;         for (int j = 0; j < n; j++)         {             printf("%c ", t % 2 == 0 ? '#' : '*');             t /= 2;         }         printf("\n");     }  	return 0; }

user: user-4
content: 递归解法，你可以自行改成迭代的。  #include <stdio.h> #include <stdlib.h>  void perm(int n, int level, int* v) {   int i, loop;   for(loop = 0; loop < n; ++loop)   {     v[level] = loop;     if(level == n-1)     {      printf("[%d", v[0]);      for(i =1; i < n; ++i)      {        printf(",%d", v[i]);      }       puts("]");     }else     {       perm(n, level+1,v);       }   } }  int main() {   int n, *v;   if(1 == scanf("%d", &n) && n > 0)   {      v = (int*)malloc(sizeof(int)* n);       if(v)      {        perm(n, 0, v);        free(v);      }   } }  //输入:3 /*输出: [0,0,0] [0,0,1] [0,0,2] [0,1,0] [0,1,1] [0,1,2] [0,2,0] [0,2,1] [0,2,2] [1,0,0] [1,0,1] [1,0,2] [1,1,0] [1,1,1] [1,1,2] [1,2,0] [1,2,1] [1,2,2] [2,0,0] [2,0,1] [2,0,2] [2,1,0] [2,1,1] [2,1,2] [2,2,0] [2,2,1] [2,2,2] */

user: user-5
content: int n = 3; for (int i = 0; i < (1 << n); i++) {      int t = i;     for (int j = 0; j < n; j++)     {         printf("%c ", t % 2 == 0 ? '#' : '*');         t /= 2;     }     printf("\n"); }