user-0 提问: 散分＋“加括号改变运算顺序的所有方案”终极代码PK和征集

回复:
user: user-1
content: 自顶！

user: user-2

user: user-3
content: 唉，想不出来，只能围观赵老师，围观大神了

user: user-4
content: 上面给的结果好像都多了1, 我用 wc -l 数输出文件的行数了...

user: user-4
content: 后缀表达式转中缀表达式啊...   后缀表达式总是前2个是 数字, 最后一个是运算符, 中间是各 n-2 个数字和运算符, 程序里用一个bit表示后缀表达式中是出现数字还是运算符, 1表示数字, 0表示运算符, 放 check里检查是否是合法的表达式... output 里把后缀表达式转成中缀表达式输出...  中缀表达式好像除了给人看也没啥用, 如果是具体计算就完全不用转中缀表达式了...

user: user-5
content: 引用 16 楼 mujiok2003 的回复: 都可以发空的， ，只能说csdn很傻

user: user-5
content: 引用 13 楼 u013163178 的回复:[quote=引用 12 楼 zhao4zhong1 的回复:] 自顶！ 为什么你输3个字也能发布，不是至少要5个字吗[/quote]  因为是【color=#000000]自顶！[/color】

user: user-6
content: 引用 13 楼 u013163178 的回复:[quote=引用 12 楼 zhao4zhong1 的回复:] 自顶！ 为什么你输3个字也能发布，不是至少要5个字吗[/quote] 因为你才3裤衩，人家都一个砖了。。

user: user-0
content: 不错，楼上的比我的快多了。求简单介绍一下思路。

user: user-4
content: 带上格式吧...  #include <stdio.h> #include <stdlib.h> #include <string.h>  int b1c( unsigned x ) { 	x = (x&0x55555555) + ((x&0xaaaaaaaa)>>1); 	x = (x&0x33333333) + ((x&0xcccccccc)>>2); 	x = (x&0x0f0f0f0f) + ((x&0xf0f0f0f0)>>4); 	x = (x&0x00ff00ff) + ((x&0xff00ff00)>>8); 	x = (x&0x0000ffff) + ((x&0xffff0000)>>16);  	return x; }  int check(int n, int v) { 	int c = 1;  	n-=2; 	while(n--) 	{ 		if(v & (1<<(2*n + 1))) 			++c; 		else if(--c < 0) 			return 0;  		if(v & (1<<2*n)) 			++c; 		else if(--c < 0) 			return 0; 	}  	return 1; }  void output(int idx, int n, int v) { 	char s_expr[16][80], expr_r[80], expr[80], *pi, *po; 	int  stack[16], ne = 1, ns = 2;  	strcpy(s_expr[0], "."); 	stack[0] = stack[1] = 0;  	n = 2 * (n-2); 	while(n--) 	{ 		if(v & (1<<n)) 		{ 			stack[ns++] = 0; 		} 		else 		{	 			--ns; 			sprintf(s_expr[ne], "(%s+%s)", s_expr[stack[ns-1]], s_expr[stack[ns]]); 			stack[ns-1] = ne++; 		} 	}  	sprintf(expr_r, "(%s+%s)", s_expr[stack[0]], s_expr[stack[1]]); 	for(n = 0, pi = expr_r, po = expr; *pi; ++pi, ++po) 	{ 		if('.' == *pi) 		{ 			++n; 			if(n < 10) 			{ 				*po = '0' + n; 			} 			else 			{ 				*po++ = '1'; 				*po   = '0' + n - 10; 			}	 		} 		else 		{ 			*po = *pi; 		} 	} 	*po = 0; 	printf("%8d: %s\n", idx, expr); }  int main(int argc, char* argv[]) { 	int n = 8, nmx, i, idx = 0;  	if(argc == 2) 		n = atoi(argv[1]);  	if(n < 2 || n > 16) 		n = 8;  	nmx = 1 << 2 * (n-2);  	for(i = 0; i < nmx; ++i) 	{ 		if(b1c(i) == n - 2 && check(n, i)) 			output(idx++, n, i); 	}	  return 0; }

user: user-4
content: 贴个慢的,  16个数的在我机器上运行时间 42秒,  9694845 个结果, 输出文件 740M ,  12个数就不测了, 好像0.3秒左右, 58786 个结果... 写个好的输出函数应该能处理 16 个数在 20多秒..  #include <stdio.h> #include <stdlib.h> #include <string.h>  int b1c( unsigned x ) { 	x = (x&0x55555555) + ((x&0xaaaaaaaa)>>1); 	x = (x&0x33333333) + ((x&0xcccccccc)>>2); 	x = (x&0x0f0f0f0f) + ((x&0xf0f0f0f0)>>4); 	x = (x&0x00ff00ff) + ((x&0xff00ff00)>>8); 	x = (x&0x0000ffff) + ((x&0xffff0000)>>16);  	return x; }  int check(int n, int v) { 	int c = 1;  	n-=2; 	while(n--) 	{ 		if(v & (1<<(2*n + 1))) 			++c; 		else if(--c < 0) 			return 0;  		if(v & (1<<2*n)) 			++c; 		else if(--c < 0) 			return 0; 	}  	return 1; }  void output(int idx, int n, int v) { 	char s_expr[16][80], expr_r[80], expr[80], *pi, *po; 	int  stack[16], ne = 1, ns = 2;  	strcpy(s_expr[0], "."); 	stack[0] = stack[1] = 0;  	n = 2 * (n-2); 	while(n--) 	{ 		if(v & (1<<n)) 		{ 			stack[ns++] = 0; 		} 		else 		{	 			--ns; 			sprintf(s_expr[ne], "(%s+%s)", s_expr[stack[ns-1]], s_expr[stack[ns]]); 			stack[ns-1] = ne++; 		} 	}  	sprintf(expr_r, "(%s+%s)", s_expr[stack[0]], s_expr[stack[1]]); 	for(n = 0, pi = expr_r, po = expr; *pi; ++pi, ++po) 	{ 		if('.' == *pi) 		{ 			++n; 			if(n < 10) 			{ 				*po = '0' + n; 			} 			else 			{ 				*po++ = '1'; 				*po   = '0' + n - 10; 			}	 		} 		else 		{ 			*po = *pi; 		} 	} 	*po = 0; 	printf("%8d: %s\n", idx, expr); }  int main(int argc, char* argv[]) { 	int n = 8, nmx, i, idx = 0;  	if(argc == 2) 		n = atoi(argv[1]);  	if(n < 2 || n > 16) 		n = 8;  	nmx = 1 << 2 * (n-2);  	for(i = 0; i < nmx; ++i) 	{ 		if(b1c(i) == n - 2 && check(n, i)) 			output(idx++, n, i); 	}	  return 0; }

user: user-0
content: 引用 23 楼 slx_391987 的回复:[quote=引用 21 楼 zhao4zhong1 的回复:] [quote=引用 20 楼 slx_391987 的回复:] 还要考虑 运算符 优先级吧。 比如全是加法，加了括号也没用。 此处的＋泛指所有双目运算符，而非算数加法。[/quote] 所以我说了 “比如”。  我的意思是，加括号的时候，需要考虑运算符的优先级，如果全是+或者-或者* 等，加了括号也不能改变运算结果。[/quote] 此题不关注运算结果是否相等，只关注给出所有加括号改变运算顺序的可能。

user: user-7
content: 引用 21 楼 zhao4zhong1 的回复:[quote=引用 20 楼 slx_391987 的回复:] 还要考虑 运算符 优先级吧。 比如全是加法，加了括号也没用。 此处的＋泛指所有双目运算符，而非算数加法。[/quote] 所以我说了 “比如”。  我的意思是，加括号的时候，需要考虑运算符的优先级，如果全是+或者-或者* 等，加了括号也不能改变运算结果。

user: user-8
content: 泛指所有双目运算符

user: user-0
content: 引用 20 楼 slx_391987 的回复:还要考虑 运算符 优先级吧。 比如全是加法，加了括号也没用。 此处的＋泛指所有双目运算符，而非算数加法。

user: user-7
content: 还要考虑 运算符 优先级吧。 比如全是加法，加了括号也没用。

user: user-6
content: 哦，嗦嘎！

user: user-9
content: 引用 12 楼 zhao4zhong1 的回复:自顶！ 为什么你输3个字也能发布，不是至少要5个字吗

user: user-0
content: 自顶！

user: user-9
content: 想了半天，还是不懂，我投降