leetcode 224 substantially Calculator

1. Topic

Calculator implemented to calculate a basic value of a simple string expression.

String expressions may comprise a left parenthesis (right parenthesis), plus +, minus -, space and non-negative integers.

Example 1:

输入: "1 + 1"
输出: 2

Example 2:

输入: " 2-1 + 2 "
输出: 3

Example 3:

输入: "(1+(4+5+2)-3)+(6+8)"
输出: 23

Description:
(1) you can assume that the given expression is valid.
(2) Do not use the built-in library functions eval.

Source: stay button (LeetCode)
link: https://leetcode-cn.com/problems/basic-calculator
copyrighted by deduction from all networks. Commercial reprint please contact the authorized official, non-commercial reprint please indicate the source.

2. My problem solution

Dual-stack method, reading back the front string handled as follows:
(1) space: Skip;
(2) left parenthesis, plus, minus: the symbol stack;
(3) digital: digital rearwardly find complete , into the stack number; if there are at least two digital numbers stack and the symbol stack, the stack is "+", "-", only one operation, digital pop stack two elements, symbols a stack element, the operation result into a digital stack;
(4) Right parenthesis: At this time, the stack must be left parenthesis symbol, a pop-up; determining whether the cycle operation can be performed (i.e., at least two digital numbers stack and the symbol stack, the stack is "+", "-"), for related operations can not be performed until the date;

Finally, the stack will be empty symbols, numbers stack only one element, that is the result.

class Solution {
	stack<int> s1;//number
	stack<string> s2;//operator
public:
	int calculate(string s) {
		int len = s.size();
		int i = 0;
		while (i<len) {
			if (s[i] == ' '){//空格
				i++;
				continue;
			}
			else if (s[i] == '(') {//左括号
				s2.push("(");
			}
			else if (s[i] == ')') {//右括号
				s2.pop();//"("
				//calc
				while (!s2.empty() && s1.size() >= 2 && (s2.top() == "+" || s2.top() == "-")) {
					int num2 = s1.top();
					s1.pop();
					int num1 = s1.top();
					s1.pop();
					if (s2.top() == "+")s1.push(num1 + num2);
					else s1.push(num1 - num2);
					s2.pop();
				}
			}
			else if (s[i] == '+') {
				s2.push("+");
			}
			else if (s[i] == '-') {
				s2.push("-");
			}
			else {//number
				int j = i + 1;
				while (s[j] >= '0' && s[j] <= '9')j++;
				s1.push(stoi(s.substr(i,j-i)));
				i = j;

				//calc
				if (s1.size() >= 2 && (s2.top() == "+" || s2.top() == "-")) {
					int num2 = s1.top();
					s1.pop();
					int num1 = s1.top();
					s1.pop();
					if (s2.top() == "+")s1.push(num1 + num2);
					else s1.push(num1 - num2);
					s2.pop();
				}
				continue;
			}
			i++;
		}

		return s1.top();
	}
};

3. someone else's problem solution

3.1 single-stack method

A stack using only values recorded will +、-be combined with the digital together, plus an integer number, the minus sign is negative, is calculated from the front rearward.
Advantages: applicable to this question, simple and easy to understand.

class Solution {
	stack<int> s1;//number
	stack<string> s2;//operator
public:
	int calculate(string s) {
		int len = s.size(), res = 0, sign = 1;
		for (int i = 0; i<len; i++) {
			//if (s[i] == ' ')continue;
			if (s[i] >= '0'&&s[i] <= '9') {
				int num = 0;
				while (i<len && s[i] >= '0' && s[i] <= '9') {
					num = 10 * num + s[i] - '0';
					i++;
				}
				res += num*sign;
				i--;
			}
			else if (s[i] == '+')
				sign = 1;
			else if (s[i] == '-')
				sign = -1;
			else if (s[i] == '(') {
				s1.push(res);
				s1.push(sign);
				res = 0;
				sign = 1;
			}
			else if (s[i] == ')') {
				res *= s1.top(); s1.pop();
				res += s1.top(); s1.pop();
			}
		}
		return res;
	}
};

3.2 turn postfix infix expression

Infix expression is a human common expressions, such as 1+2*(3+4), but computer postfix expression is common expression, the corresponding expression is 1 2 3 4 + * +, postfix notation, also known as reverse Polish notation, the order can be solved in the computer. May be transformed using the stack, conversion rules are as follows:

See order infix expression of each character string:
(1) When a numeral, and back extract the entire digital outputs;
(2) experience +、-、*、/、(, if the stack is empty, stack directly; if the stack was not empty, and the pop-top element until the output of the top element (operator) of lower priority than the current element (operator) or the top element of priority (;
(3) encounters ), the pop-top element until the case and outputs to (pay attention (to the stack, but does not output;
(4) End view string, pop the top element until the stack is empty;

Advantages: reverse Polish notation calculation is relatively easy, the string expression (infix) into reverse Polish notation recalculated value expression, this method wider adaptability, promotion is also easy, not just for to this question.

A method of determining the priority of elements:

	char order[7][7] = {
		//     +   -   *   /   (   )   #
		/*+*/ '>','>','<','<','<','>','>',
		/*-*/ '>','>','<','<','<','>','>',
		/***/ '>','>','>','>','<','>','>',
		/*/*/ '>','>','>','>','<','>','>',
		/*(*/ '<','<','<','<','<','=',' ',
		/*)*/ ' ',' ',' ',' ',' ',' ',' ',
		/*#*/ '<','<','<','<','<',' ','='
	};

The following is a method of conjugation transfer suffix code to achieve the following:

class Solution {
	stack<int> s1;//number
	stack<string> s2;//operator
	char order[7][7] = {
		//     +   -   *   /   (   )   #
		/*+*/ '>','>','<','<','<','>','>',
		/*-*/ '>','>','<','<','<','>','>',
		/***/ '>','>','>','>','<','>','>',
		/*/*/ '>','>','>','>','<','>','>',
		/*(*/ '<','<','<','<','<','=',' ',
		/*)*/ ' ',' ',' ',' ',' ',' ',' ',
		/*#*/ '<','<','<','<','<',' ','='
	};
public:
	vector<string> mid2post(string s) {
		vector<string> res;
		stack<string>().swap(s2);//clear

		for (int i = 0; i < s.size(); i++) {
			if (s[i] == ' ')continue;
			else if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/' || s[i]=='(') {
				if (s2.empty()) {//第一次,直接入栈
					s2.push(toString(s[i]));
				}
				else {//栈中运算符高的出栈
					while (!s2.empty() && order[getOrder(s2.top()[0])][getOrder(s[i])] == '>') {
						if(s2.top()!="(")res.push_back(s2.top());//直到遇到(
						else break;
						s2.pop();
					}
					s2.push(toString(s[i]));//当前符号入栈
				}
			}
			else if (s[i] == ')') {
				while (!s2.empty() && s2.top()!="(") {//直接出栈直到遇到(
					res.push_back(s2.top());
					s2.pop();
				}
				s2.pop();//"("
			}
			else {
				int j = i + 1;
				while (s[j] >= '0'&&s[j] <= '9')j++;
				res.push_back(s.substr(i, j - i));
				i=j-1;//for循环i自己会++,所以i=j-1
			}
		}
		while (!s2.empty()) {//最后不要忘了清空栈
			res.push_back(s2.top());
			s2.pop();
		}
		return res;
	}

	int getOrder(char s) {
		if (s == '+')return 0;
		else if (s == '-')return 1;
		else if (s == '*')return 2;
		else if (s == '/')return 3;
		else if (s == '(')return 4;
		else if (s == ')')return 5;
		else if (s == '#')return 6;
		return -1;
	}

	string toString(char ch) {//单个字符转字符串
		string res = "a";
		res[0] = ch;
		return res;
	}
};

After transformed into postfix notation can be used leetcode 150 computing approaches.

4. Summary and Reflection

(1) there is no auto-completion, code inspections did not used to, a lot of local topfunctions forgot to add brackets, left and right parentheses do not match well.
(2) ifand else if, it is determined i++missed or wrong, resulting in an infinite loop or mistakes.
How (3) a single character into a string? No such string constructor.

Published 32 original articles · won praise 0 · Views 436

Guess you like

Origin blog.csdn.net/weixin_43951240/article/details/103857631