【华为OD机试】仿 LISP 运算

题目

LISP 语言唯一的语法就是括号要配对。

形如 (OP P1 P2 …),括号内元素由单个空格分割。

其中第一个元素 OP 为操作符,后续元素均为其参数,参数个数取决于操作符类型。

注意:

参数 P1, P2 也有可能是另外一个嵌套的 (OP P1 P2 …) ,

当前 OP 类型为 add / sub / mul / div(全小写),分别代表整数的加减乘除法,

简单起见,所有 OP 参数个数均为 2 。

举例:

输入:(mul 3 -7)

输出:-21

输入:(add 1 2)

输出:3

输入:(sub (mul 2 4) (div 9 3))

输出:5

输入:(div 1 0)

输出:error

题目涉及数字均为整数,可能为负;

不考虑 32 位溢出翻转,计算过程中也不会发生 32 位溢出翻转,

除零错误时,输出 “error”,

除法遇除不尽,向下取整,即 3/2 = 1 

思路:

将字符串中的括号、计算类型、数值依次拆分出来,然后基于栈的方法依次放入元素,遇到右括号的时候就进行一次计算,之后抛出括号内的元素再将计算后的结果放入栈,直到栈里只有一个元素,就是结果了

代码:

#include
using namespace std;

string val(int a, int b, string type) {
	if (type == "+")
		return to_string(a + b);
	if (type == "-")
		return to_string(a - b);
	if (type == "*")
		return to_string(a * b);
	if (type == "/") {
		if (b == 0)
			return "error";
		return to_string(a / b);
	}
}

int main() {
	string str;
	int i, j, a, b;
	stack s;
	getline(cin, str);

	for (i = 0; i < str.length(); i++) {
		if (str[i] == '(') {
			s.push("(");
		} else if (str[i] == 'a' ) {
			s.push("+");
			i += 2;
		} else if (str[i] == 's' ) {
			s.push("-");
			i += 2;
		} else if (str[i] == 'm' ) {
			s.push("*");
			i += 2;
		} else if (str[i] == 'd') {
			s.push("/");
			i += 2;
		} else if (str[i] == '-' || str[i] >= '0' && str[i] <= '9') {
			string ts = "";
			ts += str[i];
			for (j = i + 1; j < str.length(); j++) {
				if (str[j] >= '0' && str[j] <= '9')
					ts += str[j];
				else
					break;
			}
			//cout << "----ts:" << ts << endl;
			s.push(ts);
			i = j - 1;
		} else if (str[i] == ')') {
			string b = s.top();
			s.pop();
			string a = s.top();
			s.pop();
			string type = s.top();
			s.pop();
			s.pop();//抛出左括号
			//cout << "---pop():" << type << " " << a << " " << b << endl;
			string sum = val(stoi(a), stoi(b), type);
			if (sum == "error") {
				cout << "error" << endl;
				return 0;
			}
			s.push(sum);
			if (s.size() == 1) {
				cout << sum << endl;
				return 0;
			}
		}
	}

	return 0;
}

你可能感兴趣的:(剑指offer,面试/笔试题,题解,华为od,算法,c++)