代码
#include <stdio.h>
#include <stdlib.h>
/*
通过递归函数实现24点游戏
对算术式 a ? b ? c ? d 从左到右顺序计算,
因为 +,-优先级相同, x, /优先级相同; 但x,/优先级高于加减优先级
所以当第1个 ? 为 +,-时先按最低优先级处理,即先不计算 a ? b。
此时,将 b 作为 第2个 ? 的左操作数, c 作为 第2个 ? 的右操作数 计算 b ? c, 当 得到 b ? c的计算结果 Rbc 后 再将 Rbc 作为 第1个 ? 的右做操作数计算 a ? Rbc
但是,当第1个 ? 为 x,/时按最高优先级处理,即先计算 a ? b = Rab,
此时,将 计算结果 Rab 作为 第2个 ? 的做操作数, c作为 第2个 ? 的右操作数 计算 Rab ? c
类似的,在计算 b ? c 或 Rab ? c时,如果第2个? 为 +,- 时,先将本次(即第2个) ? 的右操作数 做为 下一次(即第3个) ? 的左操作数去计算下一次的 ?运算
如果第2个 ? 为 x,/时, 先计算本次 ?运算,再将本次运算结果作为下一次 ?的左操作数去进行下一次 ? 运算
...
直到最后一个 ? 时,直接进行计算,再把计算结果返回至上一个 ? , 作为上一个 ? 的右操作数,最终完成所有 ? 的运算。
需要注意的是 如果当前 ? 运算为 - 时,要把当前 ? 的右操作数的相反数作为下一次 ? 运算的 左操作数 ,并且把当前为 - 运算(即减运算)的 ? 改成 + 运算(即加运算)
*/
struct Item{
int nums[4];
char signs[3];
};
int main() {
void calc(struct Item *p, int n);
int func(char sign, int num1, int num2, struct Item *p, int count);
struct Item *p;
int n,i,j;
char str[8];
scanf("%d",&n);
p = (struct Item *)malloc(n * sizeof(struct Item));
for(i=0; i<n; i++){
//要求输出的是字符串
// scanf("%s", str);
// for(j=0; j<=3; j++) {
//
// *((p+i)->nums + j) = str[2*j] - 48;
//
// if(j != 3) {
// *((p+i)->signs + j) = str[2*j+1];
// }
// }
//按如下格式输入也可以
scanf("%d%c%d%c%d%c%d",(p+i)->nums, (p+i)->signs,(p+i)->nums+1, (p+i)->signs+1,(p+i)->nums+2, (p+i)->signs+2,(p+i)->nums+3);
}
calc(p, n);
free(p);
return 0;
}
void calc(struct Item *p, int n) {
int func(char sign, int num1, int num2, struct Item *p, int count);
int result;
int i;
int count,num1,num2;
char sign;
for(i=0; i<n; i++) {
count = 1;
num1 = *((p+i)->nums);
num2 = *((p+i)->nums+1);
sign = *((p+i)->signs);
result = func(sign, num1, num2, p+i, count);
// printf("result: %d", result);
if (result == 24) {
printf("Yes\n");
}else {
printf("No\n");
}
}
}
int func(char sign, int num1, int num2, struct Item *p, int count) {
// printf("num1=%d, num2=%d, count=%d, sign=%c\n", num1, num2, count, sign);
int result;
int tmp;
if (count != 3) {
//取item.signs数组中的元素时,已传入的形参count为索引
//取item.nums数组中的元素时,需要已 count+1 为索引
//不能在形参sign的位置上已 count++ 的方式,在给形参sign赋以count原值后,妄想以形参count加1后的值 赋值给形参 num2 和 count
//因为按照这个方式,func函数中递归调用的func函数形参 num2 和 count 还是 未加 1 之前的count值
//以下注释为错误示例:
// switch(sign) {
// case '+':
// result = num1 + func(*(p->signs+(count++)), num2, *(p->nums+count), p, count);
// break;
// case '-':
// result = num1 + func(*(p->signs+(count++)), -num2, *(p->nums+count), p, count);
// break;
// case 'x':
// result = func(*(p->signs+(count++)), num1 * num2, *(p->nums+count), p, count);
// break;
// case '/':
// result = func(*(p->signs+(count++)), num1 / num2, *(p->nums+count), p, count);
// break;
// }
tmp = count;
++count;
switch(sign) {
case '+':
result = num1 + func(*(p->signs+tmp), num2, *(p->nums+count), p, count);
break;
case '-':
result = num1 + func(*(p->signs+tmp), -num2, *(p->nums+count), p, count);
break;
case 'x':
result = func(*(p->signs+tmp), num1 * num2, *(p->nums+count), p, count);
break;
case '/':
result = func(*(p->signs+tmp), num1 / num2, *(p->nums+count), p, count);
break;
}
}else {
switch(sign) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case 'x':
result = num1 * num2;
break;
case '/':
result = num1 / num2;
break;
}
}
return result;
}