请写一个整数计算器,支持加减乘三种运算和括号。
数据范围:,保证计算结果始终在整型范围内
要求:空间复杂度: ,时间复杂度
import java.util.*; public class Solution { public static int solve (String s) { Map<Character,Integer> map = new HashMap<>(); //存优先级的map map.put('-', 1); map.put('+', 1); map.put('*', 2); Deque<Integer> nums = new ArrayDeque<>(); // 数字栈 Deque<Character> opts = new ArrayDeque<>(); // 操作符栈 s.replaceAll(" ",""); // 去空格 char[] chs = s.toCharArray(); int n = chs.length; for(int i = 0; i < n; i++){ char c = chs[i]; if(isNumber(c)){ // 情况1 int num = 0; int j = i; // 读取连续数字符号 while(j < n && isNumber(chs[j])){ num = 10*num + chs[j++] - '0'; } nums.push(num); i = j - 1; }else if (c == '('){ // 情况2 opts.push(c); }else if (c == ')' ){ // 情况3 while(opts.peek() != '('){ cal(nums, opts); } opts.pop(); }else{ // 情况4 while(!opts.isEmpty() && opts.peek()!='(' && map.get(opts.peek()) >= map.get(c)){ cal(nums, opts); } opts.push(c); } } while(!opts.isEmpty()) { // 计算栈中剩余操作符 cal(nums, opts); } return nums.pop(); } public static boolean isNumber(Character c){ return Character.isDigit(c); } public static void cal(Deque<Integer> nums, Deque<Character> opts){ int num2 = nums.pop(); int num1 = nums.pop(); char opt = opts.pop(); if(opt == '+'){ nums.push(num1 + num2); }else if(opt == '-'){ nums.push(num1 - num2); }else if(opt == '*'){ nums.push(num1 * num2); } } }
递归
from collections import deque class Solution: def solve(self, s): s = deque(s) def dfs(): num, sign, stk = 0, '+', [] while s: ch = s.popleft() if ch == '(': num = dfs() if ch.isdigit(): num = num * 10 + int(ch) if (not ch.isdigit() and ch != ' ') or not s: if sign == '+': stk.append(num) elif sign == '-': stk.append(-num) elif sign == '*': stk.append(stk.pop() * num) num, sign = 0, ch if ch == ')': break return sum(stk) return dfs()
// 第一种方法 function solve( s ){ let stack = [],i = 0,sign='+',num=0; while(i < s.length){ if(s[i]=='('){ let flag= 1, start = i+1; while(flag>0){ i++; if(s[i]==')') flag--; if(s[i]=='(') flag++; } num = solve(s.slice(start,i)); i--; }else if(s[i]>='0'&&s[i]<='9'){ num = num*10 + Number(s[i]); } if((s[i]<'0'|| s[i]>'9') || i==s.length-1){ if(sign=='*') stack.push(Number(stack.pop())*num); if(sign=='+') stack.push(Number(num)); if(sign=='-') stack.push(Number(num)*-1); if(sign=='/') stack.push(Number(stack.pop())/num); sign = s[i]; num = 0; } i++; } return stack.reduce((total,n)=>{return total+n},0); } // 第二种 function solve ( s ) { return eval(s); } // 第三种 function solve ( s ) { let func = new Function(`return ${s}`); return func(); }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 返回表达式的值 * @param s string字符串 待计算的表达式 * @return int整型 */ public int solve(String s) { // 请写一个整数计算器,支持加减乘三种运算和括号。 // write code here //idea the () could be regarded as a computing element using the recursion method Stack<Integer> stack = new Stack<>(); int number = 0; int sum = 0; char sign = '+'; char[] c = s.toCharArray(); int n = s.length(); for (int i = 0; i < n; i++) { char ele = c[i]; //process the numerical situation if (Character.isDigit(ele)) { number = number * 10 + ele - '0'; } //process the () situation if (ele == '(') { int j = i + 1; int counterPar = 1; String subPar = ""; //extract the most outer group and recursevely preocess while (counterPar > 0) { if (c[j] == '(') { counterPar++; } if (c[j] == ')') { counterPar--; } j++; } subPar = s.substring(i + 1, j); number=solve(subPar); i = j-1; } //real work block if (ele != ' ' && !Character.isDigit(ele) || i == n - 1) { if (sign == '+') { stack.push(number); } else if (sign == '-') { stack.push(-1 * number); } else if (sign == '*') { stack.push(stack.pop() * number); } else if (sign == '/') { stack.push(stack.pop() / number); } //change the sign and number number = 0; sign = ele; } } while (!stack.isEmpty()) { sum+=stack.pop(); } return sum; } }
#include <string.h> //返回字符串长度 int sizestr(char* s) { int i = 0; while (s[i] != '\0') i++; return i + 1; } int solve(char* s) { // write code here int data[100], sign[100]; int no = 0, no_s = 0; for (int i = 0;s[i] != '\0';i++) { if (s[i] == '(') data[no++] = solve(s + i + 1);//遇到'('时递归 if (s[i] == ')') { memcpy(s, s + i + 1, sizestr(s + i + 1));//函数退出时,清理已经计算过的表达式,防止重复计算 break; } if (s[i] >= '0' && s[i] <= '9') { int num = 0; while (s[i] >= '0' && s[i] <= '9') {//字符数转int,存入数组 num = num * 10 + s[i] - '0'; i++; } i--; data[no++] = num; } if (s[i] == '*') {//乘法可以先计算,先算后存 i++; if (s[i] >= '0' && s[i] <= '9') { int num = 0; while (s[i] >= '0' && s[i] <= '9') { num = num * 10 + s[i] - '0'; i++; } i--; data[no - 1] *= num;//计算结果覆盖存入 } else if (s[i] == '(')//出现'*('时的情况 data[no - 1] *= solve(s + i + 1);//同样先计算括号里的 } else if (s[i] == '+') {//加减法,先存再算,此时只要存符号,数字上面存了 sign[no_s++] = s[i]; } else if (s[i] == '-') { sign[no_s++] = s[i]; } } for (int i = 0, j = 0;i < no_s;i++) {//计算 if (sign[i] == '+') { data[j + 1] = data[j] + data[j + 1]; data[j++] = 0; } else if (sign[i] == '-') { data[j + 1] = data[j] - data[j + 1]; data[j++] = 0; } } return data[no - 1]; }
char* noBlank(char *s){ char *p = (char *)malloc(sizeof(char) * (strlen(s)+1)); strcpy(p, s); int len = strlen(s); for(int i=0; i<len; i++){ if(*(p+i) == ' '){ for(int j=i; j<len; j++){ *(p+j) = *(p+j+1); } len--; i--; } } return p; } int solve(char* s ) { // write code here char *p; char *q; int t; int len = strlen(s); int quelen = 10; p = noBlank(s); int stackInt[quelen]; memset(stackInt, 0, sizeof(stackInt)); char stackChar[quelen]; memset(stackChar, 0, sizeof(stackChar)); int lock = 0; int up = 0, top = 0; while(*p != '\0'){ if(48 <= *p && *p <= 57){ //如果是数字 stackInt[up] = stackInt[up]*10 + (*p - 48); lock = 1; } else{ if(stackChar[top-1] != 0){ if(*p == ')'){ t = top; while(stackChar[t-1] != '('){ switch (stackChar[t-1]){ case '+': stackInt[up-2] = stackInt[up-2] + stackInt[up-1]; stackInt[--up] = 0; break; case '-': stackInt[up-2] = stackInt[up-2] - stackInt[up-1]; stackInt[--up] = 0; break; case '*': stackInt[up-2] = stackInt[up-2] * stackInt[up-1]; stackInt[--up] = 0; break; case '(': break; } t--; top--; } top--; } else if(*p == '('){ stackChar[top++] = *p; } else{ switch (*p){ case '*': switch (stackChar[top-1]){ case '(': stackChar[top++] = *p; break; case '*': stackInt[up-2] = stackInt[up-2] * stackInt[up-1]; stackInt[--up] = 0; stackChar[top-1] = *p; break; case '+': stackChar[top++] = *p; break; case '-': stackChar[top++] = *p; break; } break; case '+': switch (stackChar[top-1]){ case '(': stackChar[top++] = *p; break; case '*': stackInt[up-2] = stackInt[up-2] * stackInt[up-1]; stackInt[--up] = 0; stackChar[top-1] = *p; break; case '+': stackInt[up-2] = stackInt[up-2] + stackInt[up-1]; stackInt[--up] = 0; stackChar[top-1] = *p; break; case '-': stackInt[up-2] = stackInt[up-2] - stackInt[up-1]; stackInt[--up] = 0; stackChar[top-1] = *p; break; } break; case '-': switch (stackChar[top-1]){ case '(': stackChar[top++] = *p; break; case '*': stackInt[up-2] = stackInt[up-2] * stackInt[up-1]; stackInt[--up] = 0; stackChar[top-1] = *p; break; case '+': stackInt[up-2] = stackInt[up-2] + stackInt[up-1]; stackInt[--up] = 0; stackChar[top-1] = *p; break; case '-': stackInt[up-2] = stackInt[up-2] - stackInt[up-1]; stackInt[--up] = 0; stackChar[top-1] = *p; break; } break; }} } else stackChar[top++] = *p; } if(!(48 <= *(p+1) && *(p+1) <= 57) && lock == 1){ up++; lock = 0; } p++; } while(top != 0){ switch (stackChar[top-1]){ case '+': stackInt[up-2] = stackInt[up-2] + stackInt[up-1]; stackInt[--up] = 0; break; case '-': stackInt[up-2] = stackInt[up-2] - stackInt[up-1]; stackInt[--up] = 0; break; case '*': stackInt[up-2] = stackInt[up-2] * stackInt[up-1]; stackInt[--up] = 0; stackChar[top-1] = *p; break; } top--; } return stackInt[0]; }
HashMap<Character ,Integer> map=new HashMap<Character ,Integer>(){{ put('+' ,1); put('-' ,1); put('*' ,2); }}; public int solve (String s) { // write code here Stack<Character> s1=new Stack<>(); Stack<Integer> s2=new Stack<>(); s2.push(0); char[] cs=s.replaceAll(",","").toCharArray(); for(int i=0;i<cs.length;i++){ // 1、遇到左括号 if(cs[i]=='('){ s1.push('('); }else if(Character.isDigit(cs[i])){ //2、遇到数字 int num=0; while(i<cs.length && Character.isDigit(cs[i])){ num=num*10+(cs[i++]-'0'); } i--; s2.push(num); }else if(cs[i]==')'){// 3、遇到右括号 while(s1.peek()!='('){ cacl(s1 ,s2); } s1.pop(); }else{// 4、遇到计算符号 if(i>0 && cs[i-1]=='('){ // 4.1 如果左括号后紧跟一个计算符号,需要在符号前加个0 ,便于进行计算 s2.push(0); } // 4.2 符号优先级高的会先进行计算 while(!s1.isEmpty() && s1.peek()!='(' && map.get(cs[i])<=map.get(s1.peek())){ cacl(s1 ,s2); } // 4.3 处理完紧跟左括号和优先级计算,需要将当前的符号压栈 s1.push(cs[i]); } } // 5、将没计算完的情况进行计算,如只有1+2 while(!s1.isEmpty()){ cacl(s1 ,s2); } return s2.pop(); } public void cacl(Stack<Character> s1 ,Stack<Integer> s2){ if(s1.size()<1 || s2.size()<2){ return; } char c=s1.pop(); int n=s2.pop() ,m=s2.pop(); if(c=='+'){ s2.push(m+n); }else if(c=='-'){ s2.push(m-n); }else{ s2.push(m*n); } }
class Solution { public: stack<int> num; stack<char> op; //优先级表 map<char, int> h{ {'+', 1}, {'-', 1}, {'*', 2}}; void eval() { int a = num.top(); num.pop(); int b = num.top(); num.pop(); int r = 0; if (op.top() == '+') r = a + b; if (op.top() == '-') r = b - a; if (op.top() == '*') r = a * b; op.pop(); num.push(r); } int solve(string s) { for (int i = 0; i < s.size(); i++) { if (isdigit( s[i])) { //数字入栈 isdigit(x)判断x是否是阿拉伯数字1~9 int x = 0, j = i;//计算数字 while (j < s.size() && isdigit(s[j])) { x = x * 10 + s[j] - '0'; j++; } num.push(x);//数字入栈 i = j - 1; } //左括号无优先级,直接入栈 else if (s[i] == '(') { //左括号入栈 op.push(s[i]); } //括号特殊,遇到左括号直接入栈,遇到右括号计算括号里面的 else if (s[i] == ')') { //右括号 while (op.top() != '(') //一直计算到左括号 eval(); op.pop();//左括号出栈 } else { while (op.size() && h[op.top()] >= h[s[i]])//待入栈运算符优先级低,则先计算 eval(); op.push(s[i]);//操作符入栈 } } while (op.size()) eval();//剩余的进行计算 return num.top(); } };
非常好懂的,有注释喔
function solve(s) { // write code here let ops = []; // 用来存储运算符 let nums = []; // 用来存储数值和每次计算的结果 // console.log(isNaN(parseInt(s[0]))); for (let i = 0; i < s.length; i++) { if('(*'.indexOf(s[i]) > -1) { // 判断 s[i] 是否为 ( 和 * ops.push(s[i]) // 是就入栈 } else if(!isNaN(s[i])) { // 判断是否为 一个数字 ->number let temp = '' // 临时变量 while(i<s.length && !isNaN(s[i])) { temp = temp + s[i++] // 因为 s 给的是一个字符串 所以通过这个办法 可以把 两位数的数字拼在一起 } i-- // 如果 s[0] 和 s[1] 是一个操作数值12 经过上面的操作拼完了之后 i 会等于2 所以这里等让 i - 1 变回1 指向s[1] nums.push(parseInt(temp)) // 随后入栈 } else if(s[i] == '+' || s[i] == '-') { // 如果是加号 或者 减号 while(ops.length > 0 && '*+-'.indexOf(ops[ops.length - 1]) > -1) { // 就将 ops数组里 //的 * + - 等运算符 pop 出去进行操作 let num1 = nums.pop() let num2 = nums.pop() let res = calc(ops.pop(), num1, num2) // 加减乘 操作函数 在下面 nums.push(res) // 将得出的结果入栈 , 如果你有疑问, 为什么最后栈中的就一顶只有结果,没有别的操作数字, 因为 // 上面 num1 和 num2 赋值的时候 都 pop出去了 } ops.push(s[i]) // 最后将 此次遇到的 + 号丢进栈里 } else if(s[i] == ')') { // 如果遇到 ) while(ops.length > 0 && ops[ops.length - 1] != '(') { // 只要栈不空, 和不遇到 ( // 就一直循环 let num1 = nums.pop() let num2 = nums.pop() let res = calc(ops.pop(), num1, num2) // 思想和上面一样 nums.push(res) // 结果入栈 } ops.pop() // 把左括号丢出去 } } while(ops.length > 0) { // 最后 ops 不空 不停 let num1= nums.pop() let num2 = nums.pop() let temp_res = calc(ops.pop(), num1, num2) nums.push(temp_res) // 最后的结果 丢进去 } return nums.pop() // 最后的结果 return 出去 } function calc(op ,b ,a) { if(op == '+') return a + b if(op == '-') return a - b if(op == '*') return a * b return 0 } module.exports = { solve: solve, };
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 返回表达式的值 * @param s string字符串 待计算的表达式 * @return int整型 */ int solve(string s) { // write code here string cs; for (char &c : s) if (c != ' ') cs += c; int n = cs.size(); stack<int> nums; nums.push(0); stack<char> ops; for (int i = 0; i < n; ++i) { char c = cs[i]; if (c == '(') ops.push(c); else if (c == ')') { while (!ops.empty()) { if (ops.top() != '(') calc(nums, ops); else { ops.pop(); break; } } } else { if (isdigit(c)) { int u = 0, j = i; while (j < n && isdigit(cs[j])) u = u * 10 + (cs[j++] - '0'); nums.push(u); i = j - 1; } else { if (i > 0 && (cs[i - 1] == '(' || cs[i - 1] == '+' || cs[i - 1] == '-')) { nums.push(0); } while (!ops.empty() && ops.top() != '(') { char prev = ops.top(); if (m[prev] >= m[c]) { calc(nums, ops); } else { break; } } ops.push(c); } } } while (!ops.empty() && ops.top() != '(') calc(nums, ops); return nums.top(); } void calc(stack<int> &nums, stack<char> &ops) { if (nums.empty() || nums.size() < 2) return; if (ops.empty()) return; int b = nums.top(); nums.pop(); int a = nums.top(); nums.pop(); char op = ops.top(); ops.pop(); int ans = 0; if (op == '+') ans = a + b; else if (op == '-') ans = a - b; else if (op == '*') ans = a * b; nums.push(ans); } unordered_map<char, int> m = {{'-', 1}, {'+', 1}, {'*', 2}}; };
import java.util.*; public class Solution { public int solve (String s) { // 单栈+递归 char[] arr = s.replaceAll(" ","").toCharArray(); LinkedList<Integer> stack=new LinkedList<>(); int num=0; char sign='+'; for(int i=0;i<arr.length;i++){ char c=arr[i]; if(Character.isDigit(c)){ num=num*10+c-'0'; } //遇到括号就截取括号内的字符串,再递归 if(c=='('){ int j=i+1; int flag=1; while(flag>0){ if(arr[j]=='(') flag++; if(arr[j]==')') flag--; j++; } num=solve(s.substring(i+1,j-1)); i=j-1; } if(!Character.isDigit(c) || i==arr.length-1){ //+-直接放,*/栈顶*num(遍历到的数字)再放 if(sign == '+') stack.push(num); else if(sign == '-') stack.push(-1 * num); else if(sign == '*') stack.push(stack.pop() * num); else if(sign == '/') stack.push(stack.pop() / num); num=0; sign=c; } } int res=0; while(!stack.isEmpty()){ res+=stack.pop(); } return res; } }
function solve( s ) { // write code here return ~~eval(s) }
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 返回表达式的值 * @param s string字符串 待计算的表达式 * @return int整型 */ int solve(string s) { vector<string> nums; int len=s.size(); // int pre=0; stack<char> sign; unordered_map<char,int> priority={{'(',0},{'+',1},{'-',1},{'*',2},{')',3}}; for(int i=0;i<len;++i) { if(s[i]>='0' && s[i]<='9') { int j=i+1; while(j<len && s[j]>='0' && s[j]<='9') ++j; nums.push_back(s.substr(i,j-i)); i=j-1; } else { //运算符 if(s[i]==')') { while(sign.top()!='(') { //将优先级小于等于当前符号的之前的符号出栈 nums.push_back(string(1,sign.top())); sign.pop(); } sign.pop(); } else if(s[i]=='(') { sign.push(s[i]); }else { while(!sign.empty() && priority[sign.top()]>=priority[s[i]]) { //将优先级大于等于当前符号的之前的符号出栈 nums.push_back(string(1,sign.top())); sign.pop(); } sign.push(s[i]); } } } while(!sign.empty()) { nums.push_back(string(1,sign.top())); sign.pop(); } stack<int> res; for(string& cur: nums) { if(cur[0]>='0' && cur[0]<='9') { res.push(atoi(cur.c_str())); } else { int b=res.top(); res.pop(); int a=res.top(); res.pop(); switch(cur[0]) { case '+': res.push(a+b); break; case '-': res.push(a-b); break; case '*': res.push(a*b); break; } } } return res.top(); } };
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 返回表达式的值 * @param s string字符串 待计算的表达式 * @return int整型 */ int solve(string s) { vector<string> tokens = toRPN(s); return helper(tokens); } private: //运算符优先级 int priority(string &s) { if(s == "*") return 2; if(s == "+" || s == "-") return 1; if(s == "(") return 0; return -1; } //转化为逆波兰式 vector<string> toRPN(string &str) { int i = 0, n = str.size(); vector<string> s; while (i < n) { string temp = ""; if(isdigit(str[i])) while (i < n && isdigit(str[i])) { temp += str[i]; ++i; } else temp += str[i++]; s.push_back(temp); } n = s.size(); stack<string> st; vector<string> res; for (auto &it : s) { if (isdigit(it[0])) { res.push_back(it); } else if (st.empty() || it == "(") st.push(it); else if (it == ")") { while (!st.empty() && st.top() != "(") { res.push_back(st.top()); st.pop(); } st.pop(); } else { while (priority(it) <= priority(st.top())) { res.push_back(st.top()); st.pop(); if (st.empty()) break; } st.push(it); } } while (!st.empty()) { res.push_back(st.top()); st.pop(); } return res; } //逆波兰式求值 int helper(vector<string> &t) { stack<int> num; for(int i = 0;i < t.size();++i) { if(t[i] == "+" || t[i] == "-" || t[i] == "*") { int res; int n2 = num.top(); num.pop(); int n1 = num.top(); num.pop(); switch(t[i][0]) { case '+': res = n1 + n2; break; case '-': res = n1 - n2; break; case '*': res = n1 * n2; break; } num.push(res); } else num.push(stoi(t[i])); } return num.top(); } };
import java.util.*; public class Solution { public int cal(int k2,int k1,char o){ if(o=='+'){ return k2+k1; }else if(o=='-'){ return k2-k1; }else{ return k2*k1; } } public int solve (String s) { //"(3+4)*(5+(2-3))" Stack<Integer> num = new Stack<>(); Stack<Character> op = new Stack<>(); int i = 0; while(i<s.length()){ if(s.charAt(i)>='0' && s.charAt(i)<='9'){ int k = 0; while(i<s.length() && s.charAt(i)>='0' && s.charAt(i)<='9'){ k = 10*k + (s.charAt(i)-'0'); i++; } num.push(k); }else{ if(s.charAt(i)=='(') op.push(s.charAt(i)); else if(s.charAt(i)==')'){ while(op.peek()!='('){ int k1 = num.pop(); int k2 = num.pop(); char o = op.pop(); num.push(cal(k2,k1,o)); } op.pop(); }else if(s.charAt(i)=='*'){ //乘号不影响运算结果,不需要区分前一个运算符是加号还是乘号 op.push(s.charAt(i)); }else{ while(num.size()>=2){ if(op.peek()=='(')//注意 运算符不能越过小括号 break; int k1 = num.pop(); int k2 = num.pop(); char o = op.pop(); num.push(cal(k2,k1,o)); } op.push(s.charAt(i)); } i++; } } while(!op.isEmpty()){ int k1 = num.pop(); int k2 = num.pop(); char o = op.pop(); num.push(cal(k2,k1,o)); } int res = num.pop(); return res; } }