C语言 字符串算式求解

392 阅读2分钟

函数功能:

根据给定的不定长字符串算式,求出结果。数字为整数,且不会出现因除法导致除不尽的情况。

输入样例:"20+5-2*200+(32-5)/3+4-4*25/(2)"

计算结果:-290

栈相关细节参考另一篇文章。计算方式一样,栈节点内容做了微调。

栈节点类型

typedef struct StackNode {

bool isNum;
int value;
struct StackNode* up;
struct StackNode* down;

}StackNode;

全局变量

  • StackNode* gl_Top;
  • StackNode* gl_Bottom;
  • int gl_stackSize = 0;
  • int gl_maxSize = 0;

算式解析函数

int calculatorStr2Int(char* inStr) {

int i = 0, j = 0;
int value = 0;
StackNode* tmp = gl_Bottom;

if (inStr == NULL)
	return -1;
initStack(-1);
for (i = 0; inStr[i]!=0; i++) {
	if (inStr[i] <48 || inStr[i] >(48 + 9)) {//本拍是符号
		if (value != 0) {//把上一拍的数字压入栈
			push(value, true);
			value = 0;
			//如该数的前一个运算符是*或/,先计算
			if (gl_Top->down->isNum == false && (gl_Top->down->value == '*' || gl_Top->down->value == '/') && gl_stackSize >1) {
				if (gl_Top->down->value == '*') {
					gl_Top->down->down->value *= gl_Top->value;
				}
				else {
					gl_Top->down->down->value /= gl_Top->value;
				}
				pop();
				pop();
			}
		}
		
		if(inStr[i] == '+'|| inStr[i] == '-')	
			push(inStr[i],false);
		else if(inStr[i] == '*' || inStr[i] == '/')
			push(inStr[i], false);
		else if (inStr[i] == '(' || inStr[i] == ')')
			push(inStr[i], false);
		else {
			printf("字符错误\n");
			return -1;
		}
		//欲括回,计算括号内容
		if (inStr[i] == ')') {
			pop();//先把扩回')'出掉
			if (gl_Top->down->value == '(' && gl_Top->down->isNum == false) {//欲括号内无只有数字的情况:(3)
				gl_Top->down->value = gl_Top->value;
				gl_Top->down->isNum = true;
				pop();
				continue;
			}
			for (j = 0;;j++) {//遍历直到计算完括号内容
				if (gl_Top->down->value == '+' && gl_Top->down->isNum == false) {
					gl_Top->down->down->value += gl_Top->value;
					pop();
					pop();
				}
				else if (gl_Top->down->value == '-' && gl_Top->down->isNum == false) {
					gl_Top->down->down->value -= gl_Top->value;
					pop();
					pop();
				}

				if (gl_Top->down->value == '(' && gl_Top->down->isNum == false) {
					gl_Top->down->value = gl_Top->value;
					gl_Top->down->isNum = true;
					pop();
					break;
				}
			}
		}
	}
	else {
		value = value * 10 + (inStr[i] - 48);//累加读到的字符
		if (inStr[i + 1] == 0)//当计算到最右一个数字时
			push(value,true);
	}
}

for (i = 0; gl_stackSize > 1; i++) {//到这里算式会变成若干数字相加减状态,进行最终计算
	if (gl_Top->down->isNum == false && gl_Top->down->value == '+') {
		gl_Top->down->down->value += gl_Top->value;
		pop();
		pop();
	}
	else {
		gl_Top->down->down->value -= gl_Top->value;
		pop();
		pop();
	}
}
value = gl_Bottom->value;
initStack(-1);//释放栈
return value;

}