给定一个合法的表达式字符串,其中只包含非负整数、加法、减法以及乘法符号(不会有括号),例如7+3*4*5+2+4-3-1,请写程序计算该表达式的结果并输出;
给定一个合法的表达式字符串,其中只包含非负整数、加法、减法以及乘法符号(不会有括号),例如7+3*4*5+2+4-3-1,请写程序计算该表达式的结果并输出;
输入有多行,每行是一个表达式,输入以END作为结束
每行表达式的计算结果
7+3*4*5+2+4-3-1 2-3*1 END
69 -1
每个表达式的长度不超过10000,保证所有中间结果和最后结果在[-2e9,2e9]范围内
#include<iostream> #include<stack> using namespace std; // 运算符号优先级比较函数 bool priorCompare(char a,char b){ // 如果到字符串末尾则返回false if(a=='\0') return false; if(a=='*'){ if(b=='*') return false; else return true; } else return false; } // 计算结果 int getCalc(int a,int b,char sign){ if(sign=='*') return a*b; else if(sign=='+') return a+b; else return a-b; } int main(){ stack<char> sign; // 运算符号栈 stack<int> result; // 数字栈 string input; cin>>input; while(input!="END"){ string digits=""; for(int i=0;i<=input.length();i++){ char c=input[i]; // 如果当前字符仍是数字则将其连接在之前的数字字符串上,并循环到下一个字符 if(isdigit(c)) digits+=c; else{ // 当前字符是运算符,则先把上一个完整的数字放进数字栈result中 { result.push(atoi(digits.c_str())); digits=""; } // 若当前运算符号优先级低于运算符号栈顶的运算符号,则计算数字栈顶两个元素的结果,并将结果如栈,循环直到符号栈空或当前符号优先级大于符号栈顶符号 while(!sign.empty()&&!priorCompare(c,sign.top())){ int b=result.top(); result.pop(); int a=result.top(); result.pop(); result.push(getCalc(a,b,sign.top())); sign.pop(); } // 不满足上述条件,就将当前符号压入符号栈 sign.push(c); } } // 计算完毕,输出结果。 cout<<result.top()<<endl; // 清空数字栈 result.pop(); // 清空符号栈 sign.pop(); cin>>input; } return 0; }
#include <stdio.h> #include <string.h> #include <stack> using namespace std; #define ctoi(x) x=='+'? 0 : x=='-' ? 1 : x=='*' ? 2 :3 int pr[4][4]= { 1,1,0,1, 1,1,0,1, 1,1,1,1, 0,0,0,0 }; int main() { stack<int> nums; stack<int> op; char str[10000]; while(gets(str)) { if(strcmp(str,"END") == 0) break; while(!nums.empty()) nums.pop(); while(!op.empty()) op.pop(); op.push(3); int len =strlen(str); str[len]='#'; int idx=0; while(idx<=len) { if(str[idx]== ' ') { idx++; } else if(str[idx]>='0'&&str[idx]<='9') { int tmp=0; while(str[idx]>='0'&&str[idx]<='9') { tmp=tmp*10+str[idx]-'0'; idx++; } nums.push(tmp); } else { while(pr[op.top()][ctoi(str[idx])]==1) { int x2=nums.top(); nums.pop(); int x1=nums.top(); nums.pop(); int rst; int ops =op.top(); op.pop(); switch(ops){ case 0: rst=x1+x2;break; case 1: rst=x1-x2;break; case 2: rst=x1*x2;break; } nums.push(rst); } op.push(ctoi(str[idx])); idx++; } } if(op.size()==2) { printf("%d\n",nums.top()); } } return 0; }
import java.util.*; public class Main { public static void main(String[] args) { Scanner reader = new Scanner(System.in); ArrayList<String> list = new ArrayList<>(); String str = ""; while (!"END".equals(str = reader.nextLine())) { list.add(str); } list.forEach(Main::Fun); } public static void Fun(String str) { LinkedList<Integer> nums = new LinkedList<>(); LinkedList<Character> ops = new LinkedList<>(); int i = 0; while (i < str.length()) { if (str.charAt(i) >= '0' && str.charAt(i) <= '9') { int start = i; i++; while (i < str.length() && (str.charAt(i) >= '0' && str.charAt(i) <= '9')) { i++; } String a = i == str.length() - 1 ? str.substring(start) : str.substring(start, i); nums.add(Integer.parseInt(a)); } else { ops.add(str.charAt(i)); i++; } } Stack<Integer> stack = new Stack<>(); if (nums.size() < 2) { return; } stack.push(nums.poll()); stack.push(nums.poll()); while (!ops.isEmpty()) { char op = ops.poll(); if ((op == '+' || op == '-') && (!ops.isEmpty() && (ops.getFirst() == '*'))) { //如果加法、减法后面一个操作是乘法,则乘法优先操作 if (!nums.isEmpty()) { stack.push(nums.poll()); int a = stack.pop(); int b = stack.pop(); stack.push(a * b); ops.poll(); ops.addFirst(op); } else { return; } } else { if (op == '+') { int a = stack.pop(); int b = stack.pop(); stack.push(a + b); } else if (op == '-') { int a = stack.pop(); int b = stack.pop(); stack.push(b - a); } else if (op == '*') { int a = stack.pop(); int b = stack.pop(); stack.push(a * b); } if(!nums.isEmpty()){ stack.push(nums.poll()); } } } System.out.println(stack.pop()); } }
#include <bits/stdc++.h> using namespace std; int main(){ string str; while(cin >> str){ if(str[0] == 'E') break; stack<int> nums; stack<char> fu; string tmp = ""; for(char c : str){ if(c == '*' || c=='+' || c=='-'){ if(!fu.empty() && fu.top() == '*'){ int right = stoi(tmp); int left = nums.top(); nums.pop(); nums.push(left * right); fu.pop(); } else { nums.push(stoi(tmp)); } tmp = ""; fu.push(c); } else { tmp += c; } } if(fu.top() == '*'){ int right = stoi(tmp); int left = nums.top(); nums.pop(); nums.push(left * right); fu.pop(); } else { nums.push(stoi(tmp)); } int ans = 0; while(!fu.empty()){ if(fu.top() == '+') ans += nums.top(); else ans -= nums.top(); nums.pop(); fu.pop(); } ans += nums.top(); cout<<ans<<endl; } return 0; }
#include<bits/stdc++.h> using namespace std; int p[4][4] = {{1,1,0,1}, {1,1,0,1}, {1,1,1,1}, {0,0,0,0}}; map<char,int> C; int main(){ C['+'] = 0; C['-'] = 1; C['*'] = 2; C['#'] = 3; string s; while(cin>>s){ if(s=="END") break; stack<int> V; stack<int> S; S.push(3); int l = s.length(); s += '#'; for(int i=0;i<=l;){ if(s[i]==' ') i++; else if(isdigit(s[i])){ int x = 0; while(isdigit(s[i])){ x = 10*x + s[i]-'0'; i++; } V.push(x); }else{ while(p[S.top()][C[s[i]]]==1){ int y = V.top(); V.pop(); int x = V.top(); V.pop(); int op = S.top(); S.pop(); if(op==0) V.push(x+y); else if(op==1) V.push(x-y); else if(op==2) V.push(x*y); } S.push(C[s[i]]); i++; } } if(S.size()==2) cout<<V.top()<<endl; } return 0; }
def calculate(string): stack = [] i, opt = 0, "" while i < len(string): if string[i].isdigit(): tmp = "" while i < len(string) and string[i].isdigit(): tmp += string[i] i += 1 if opt == "+" or opt == "": stack.append(int(tmp)) elif opt == "-": stack.append(-int(tmp)) elif opt == "*": stack[-1] *= int(tmp) else: opt = string[i] i += 1 print(sum(stack)) while True: string = input() if string == "END": break else: calculate(string)
#include<iostream> #include<stdlib.h> #include<string.h> using namespace std; struct Node { int val; Node *next; Node():val(0),next(NULL){ } }; int main() { string S; while(cin>>S) { if(S != "END") { string str,str1,str2; int num[3] = {0},val = 0; Node *Head = new Node; Node *currentNode = Head; for(int i=0;i<S.length();++i)//将数字和符号分开 { if(S[i]>='0' && S[i]<='9') { val = val*10+S[i]-'0'; } else if(S[i]=='*' || S[i]=='-' || S[i]=='+') { Node *newNode = new Node; //数字存放再链表中 newNode->val = val; currentNode->next = newNode; currentNode = newNode; val = 0; str += S[i]; if(S[i]=='*') num[0]++; if(S[i]=='-') num[1]++; if(S[i]=='+') num[2]++; } if(i== S.length()-1) { Node *newNode = new Node; newNode->val = val; currentNode->next = newNode; currentNode = newNode; } } currentNode = Head->next; Node *preNode = Head; while(num[0] != 0)//先算乘法 { int idx = str.find('*'); for(int i=0;i<idx+1;++i) { preNode = currentNode; currentNode = currentNode->next; } preNode->val = currentNode->val * preNode->val;保留计算的结果 preNode->next = currentNode->next;//算完的从链表中删除, str1 = str.substr(0,idx); str2 = str.substr(idx+1,str.length()-idx-1);//删除已用过的符号 str = str1+str2; currentNode = Head->next; preNode = Head; num[0]--; } while(num[1] != 0) { int idx = str.find('-'); for(int i=0;i<idx+1;++i) { preNode = currentNode; currentNode = currentNode->next; } preNode->val = preNode->val - currentNode->val; preNode->next = currentNode->next; str1 = str.substr(0,idx); str2 = str.substr(idx+1,str.length()-idx-1); str = str1+str2; currentNode = Head->next; preNode = Head; num[1]--; } int Y=0; while(currentNode)//除了乘法和减法,剩下的全是加法,累加得最终结果 { Y += currentNode->val; currentNode = currentNode->next; } cout<<Y<<endl; } } return 0; }应用链表的知识
对于js来说eval 就完事了while(line=readline()){var lines = line.split('\r');for(var i=0;i<lines.length;i++){if(lines[i]=='END') break;else print(eval(lines[i]));}}
class MainActivity: def main(self): while True: # Read the data s = input() if s == 'END': break # Get the result result = eval(s) print(result) if __name__ == '__main__': M = MainActivity() M.main()方法二:用栈模拟
class MainActivity: def main(self): while True: # Read the data s = input() if s == 'END': break # Initialization stack = [] negativeFlag = False timesFlag = False numCache = [] # Traverse for char in s: if char == '+': num = int(''.join(numCache)) numCache = [] if negativeFlag: num = -num if timesFlag: stack.append(num * stack.pop()) else: stack.append(num) timesFlag = False negativeFlag = False elif char == '-': num = int(''.join(numCache)) numCache = [] if negativeFlag: num = -num if timesFlag: stack.append(num * stack.pop()) else: stack.append(num) timesFlag = False negativeFlag = True elif char == '*': num = int(''.join(numCache)) numCache = [] if negativeFlag: num = -num if timesFlag: stack.append(num * stack.pop()) else: stack.append(num) timesFlag = True negativeFlag = False else: numCache.append(char) if numCache: num = int(''.join(numCache)) numCache = [] if negativeFlag: num = -num if timesFlag: stack.append(num * stack.pop()) else: stack.append(num) # Get the result result = sum(stack) print(result) if __name__ == '__main__': M = MainActivity() M.main()
import java.io.*; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str = ""; while (str.indexOf("END") == -1){ str+= (br.readLine() + ","); } str = str.substring(0,str.indexOf("END")-1); String[] arr = str.split(","); for(int i=0;i<arr.length;i++){ System.out.println(calcFunc(arr[i])); } } static int calcFunc(String ne){ String operators = "+-*"; char lastOperator = '+'; //上个运算符 char tempOperator = ' '; //临时运算符 int lastValue = 0; //上个值 int previousVal = 0; //上上个值 String currVal = ""; char temp = ' '; int sum = 0; for(int i=0;i<ne.length();i++){ temp = ne.charAt(i); if(operators.indexOf(temp) != -1){ lastValue = lastOperator!='*'?Integer.valueOf(currVal):lastValue*Integer.valueOf(currVal); currVal = ""; if(temp == '*'){ if(lastOperator == '*'){ lastOperator = temp; }else{ tempOperator = lastOperator; lastOperator=temp; } }else{ if(lastOperator == '*'){ sum +=previousVal; previousVal = Integer.valueOf(""+tempOperator+lastValue); lastOperator = temp; }else{ sum += previousVal; previousVal = lastOperator == '+'? lastValue : Integer.valueOf(""+lastOperator+lastValue); lastOperator = temp; } } }else{ currVal += temp; if(i == ne.length()-1){ if(lastOperator == '*'){ lastValue = lastValue * Integer.valueOf(currVal); if(tempOperator == '-'){ sum += (previousVal - lastValue); }else { sum +=(previousVal + lastValue); } }else{ sum +=(previousVal + Integer.valueOf(""+lastOperator + currVal)); } } } } return sum; } }
import java.util.Arrays; import java.util.List; import java.util.Scanner; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while(sc.hasNext()){ String str = sc.next(); if(!str.equals("END")) { printNum(str); } } } private static int multiplication(String str){ String[] multStr = str.split("[/*]"); int j = 1; for (String s1 : multStr) { j = Integer.parseInt(s1)*j; } return j; } private static int sub(String str){ String[] subStr = str.split("[/-]"); int j = 0; for (int i = 0; i < subStr.length; i++) { if (i==0){ //第一个肯定是+ 因为最开始就是截取的+号 j+=Integer.parseInt(subStr[i]) ; }else { j-=Integer.parseInt(subStr[i]) ; } } return j; } private static void printNum(String str){ int res = 0; String[] addSplit = str.split("[/+]"); //如果长度为1 说明没有加法 if (addSplit.length==1){ String[] subSplit = str.split("[/-]"); //这个说明没有减法 if (subSplit.length == 1){ int multiplication = multiplication(str); System.out.println(multiplication); }else { System.out.println(subNum(Arrays.asList(subSplit))); } }else { //包含乘法的 List<String> multiplication = Arrays.stream(addSplit).filter(s -> s.contains("*")&& !s.contains("-")).collect(Collectors.toList()); //包含减法的 List<String> sub = Arrays.stream(addSplit).filter(s -> !s.contains("*")&&s.contains("-")).collect(Collectors.toList()); List<String> subAndMult = Arrays.stream(addSplit).filter(s -> s.contains("*")&&s.contains("-")).collect(Collectors.toList()); for (String s : subAndMult) { res +=subNum(Arrays.asList(s.split("[/-]"))); } //不含乘法,减法 剩下来的就是数字 List<String> addNum = Arrays.stream(addSplit).filter(s -> !s.contains("*") && !s.contains("-")).collect(Collectors.toList()); for (String s : multiplication) { res +=multiplication(s); } for (String s : sub) { res +=sub(s); } for (String s : addNum) { res += Integer.parseInt(s); } System.out.println(res); } } //只包括减法 乘法的 public static int subNum(List<String> subSplit){ int res = 0; //包含乘法的 List<String> multiplication = subSplit.stream().filter(s -> s.contains("*")).collect(Collectors.toList()); List<String> subNum = subSplit.stream().filter(s -> !s.contains("*")).collect(Collectors.toList()); for (String s : multiplication) { res-= multiplication(s); } for (String s : subNum) { res -= Integer.parseInt(s); } String firstStr = subSplit.get(0); if (firstStr.contains("*")){ res += 2*multiplication(firstStr); }else { res += 2*Integer.parseInt(firstStr); } return res; } }
import java.util.*; public class Main{ public static void main(String args[]){ Scanner sc = new Scanner(System.in); while(sc.hasNext()){ String str = sc.next(); if(!str.equals("END")){ int res=0; int d=0; char sign='+'; Stack<Integer> S = new Stack<>(); for(int i=0;i<str.length();++i){ char c = str.charAt(i); if(c>='0'){ d = d*10 -'0' + c; } if((c<'0')||i==str.length()-1){ if(sign=='+'){ S.push(d); } else if(sign=='-'){ S.push(-d); } else if(sign=='*'){ int tmp = S.peek()*d; S.pop(); S.push(tmp); } d=0; sign=c; } } while(!S.isEmpty()){ res+=S.peek(); S.pop(); } System.out.println(res); } } } }
先将中缀表达式转换为后缀表达式,再通过后缀表达式求值,有助于练习栈的应用,虽然有点麻烦 #include <iostream> #include <vector> #include <string> #include <stack> #include <algorithm> using namespace std; /* 先判断数组oper的栈顶运算符的优先级,栈顶运算符的优先级大于该运算符 那么将栈顶的运算符出栈,并入栈到数组num中,重复步骤3,如果栈顶运算符优先级小于该运算符,那么直接将该运算符入栈到opera中 */ vector<string> infixTosuffix(string str) { stack<string> num; //数值栈 stack<string> oper; //符号栈 oper.push("#"); //栈底元素 num.push("#"); //栈底元素 vector<string> operat{ "#","+","-","*","/" }; vector<char> oopp{ '#','+','-','*','/' }; for (int i = 1; i < str.size(); ++i) { char ch = str[i]; if (ch == '+') { while (oper.top() != "#") { num.push(oper.top()); oper.pop(); } oper.push("+"); } else if (ch == '-') { while (oper.top() != "#") { num.push(oper.top()); oper.pop(); } oper.push("-"); } else if (ch == '*') { while (oper.top() == "*" || oper.top() == "/") { num.push(oper.top()); oper.pop(); } oper.push("*"); } else if (ch == '/') { while (oper.top() == "*" || oper.top() == "/") { num.push(oper.top()); oper.pop(); } oper.push("/"); } else { bool isTrue = false; for (char s : oopp) { if (str[i - 1] == s) { isTrue = true; break; } } if (isTrue) { string number(1, ch); num.push(number); } else num.top().push_back(ch); } } while (oper.top() != "#") { num.push(oper.top()); oper.pop(); } vector<string> result; while (num.top() != "#") { result.push_back(num.top()); num.pop(); } reverse(result.begin(), result.end()); return result; } /* 后缀表达式计算: 遇到数值的时候入栈,当遇到运算符,连续两次出栈 将两个出栈元素结合运算符进行运算,结果入栈 如此往复直到扫描到终止符\0,此时栈底元素即为表达式的值 */ int caSuffix(vector<string> suffix) { stack<int> exp; for (string str : suffix) { int a = 0, b = 0; if (str == "+") { b = exp.top(); exp.pop(); a = exp.top(); exp.pop(); exp.push(a + b); } else if (str == "-") { b = exp.top(); exp.pop(); a = exp.top(); exp.pop(); exp.push(a - b); } else if (str == "*") { b = exp.top(); exp.pop(); a = exp.top(); exp.pop(); exp.push(a * b); } else if (str == "/") { b = exp.top(); exp.pop(); a = exp.top(); exp.pop(); if (b == 0) { cout << "ERROR" << '\n'; return 0; } exp.push(a / b); } else { a = stoi(str); exp.push(a); } } return exp.top(); } int main() { string infixExp; //89*23+45*36 while (cin >> infixExp && infixExp != "END") { infixExp.insert(infixExp.begin(), '#'); vector<string> suffixExp = infixTosuffix(infixExp); cout << caSuffix(suffixExp) << '\n'; } return 0; }