请写一个整数计算器,支持加减乘三种运算和括号。
数据范围:
,保证计算结果始终在整型范围内
要求:空间复杂度:
,时间复杂度
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];
} 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;
}
} 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}};
}; 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();
}
};