测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
1 + 2 4 + 2 * 5 - 7 / 11 0
3.00 13.36
using namespace std; #include <iostream> #include <cstring> #include <stack> #include <sstream> #include <map> #include <iomanip> template<class out_type, class in_value> out_type convert(const in_value & t){ stringstream stream; stream << t; out_type result; stream >> result; return result; } double func(char s, double m, double n){ if(s == '*')return n*m; if(s == '/')return double(n/(m*1.0)); if(s == '+')return n+m; return n-m; } int main(){ string str; map<char, int> pr = { {'*', 2}, {'/', 2}, {'+', 1}, {'-', 1}, {'#', 0} }; while(getline(cin, str) and str != "0"){ stack<char> m; stack<double> n; istringstream is(str); string s; while(is>>s){ if(s[0] >= '0' and s[0] <= '9'){ n.push(convert<double>(s)); } else{ if(!m.empty()){ if(pr[m.top()] >= pr[s[0]]){ while(!m.empty() and pr[m.top()] >= pr[s[0]]){ double t1 = n.top(); n.pop(); double t2 = n.top(); n.pop(); char ss = m.top(); m.pop(); n.push(func(ss, t1, t2)); } m.push(s[0]); } else{ m.push(s[0]); } } else{ m.push(s[0]); } } } while(!m.empty()){ double t1 = n.top(); n.pop(); double t2 = n.top(); n.pop(); char ss = m.top(); m.pop(); n.push(func(ss, t1, t2)); } printf("%.2f\n", n.top()); n.pop(); } return 0; }
//1.根据运算符划分数字数组和字符数组2.处理乘法除法变换数字数组3.处理加减法获得结果 #include<stdio.h> int main() { char a[200],fuhao[100]; float number[100]={0};int i,j,num; gets(a); num=0;//0---num数字的下标 0-num-1符号的下标 //1.把数字符号 划分到两个数组 for(i=0;a[i]!='\0';i++) { if(a[i]>='0'&&a[i]<='9') { number[num]=number[num]*10+(a[i]-'0');//解决位数问题 } else if(a[i]=='+'||a[i]=='-'||a[i]=='*'||a[i]=='/'){ fuhao[num]=a[i]; num++; } } //2.处理乘法除法 for(i=0;i<num;i++) { if(fuhao[i]=='*') { number[i]=number[i]*number[i+1];//两个数字相乘放在当前位置 for(j=i+1;j<=num;j++)//把乘除的两个数变成一个数 后面的数字前移 number[j]=number[j+1]; for(j=i;j<num;j++) //后面的符号前移 fuhao[j]=fuhao[j+1]; num--;i--;//长度减一, 再从当前位置开始计算 } if(fuhao[i]=='/') { number[i]=number[i]/number[i+1]; for(j=i+1;j<=num;j++) number[j]=number[j+1]; for(j=i;j<num;j++) fuhao[j]=fuhao[j+1]; num--;i--; } } //3.处理加减法 float sum=number[0]; for(i=0;i<num;i++) { if(fuhao[i]=='+') sum+=number[i+1]; if(fuhao[i]=='-') sum-=number[i+1]; } printf("%.2f\n",sum); return 0; }
#include <bits/stdc++.h> using namespace std; double factor(); double term(); double expression(); char cleanspace(char ch){ if(ch==' ') { cin.get(); ch=cin.peek(); } return ch; } double factor() { double result=0; char ch=cin.peek(); ch=cleanspace(ch); if(ch=='('){ cin.get(); result=expression(); cin.get(); } else{ while(isdigit(ch)){ cin.get(); result=result*10+ch-'0'; ch=cin.peek(); ch=cleanspace(ch); } } return result; } double term() { double result=factor(); while(true) { char ch=cin.peek(); ch=cleanspace(ch); if(ch=='*'||ch=='/'){ cin.get(); double value=factor(); if(ch=='*') result*=value; else if(ch=='/') result/=value; } else break; } return result; } double expression() { double result =term(); while(true) { char ch=cin.peek(); ch=cleanspace(ch); if(ch=='+'||ch=='-'){ cin.get(); double value=term(); if(ch=='+') result+=value; else if(ch=='-') result-=value; } else break; } return result; } int main() { cout<<fixed<<setprecision(2)<<expression()<<endl; return 0; }
import java.text.DecimalFormat; import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()){ String s = scanner.nextLine(); s=s.replace(" ",""); //中缀表达式转为后缀表达式 List<String> s1=transform(s); //后缀表达式计算求值 double result= calculate(s1); DecimalFormat f = new DecimalFormat("0.00"); System.out.println(f.format(result)); } } private static List<String> transform(String s) { Stack<String> stack = new Stack<>(); ArrayList<String> list = new ArrayList<>(); for (int i = 0; i < s.length(); i++) { String c= String.valueOf(s.charAt(i)); switch (c){ //统一 + - 处理 case "+": case "-": while (!stack.empty()) list.add(stack.pop()); stack.push(c); break; //统一 * / 处理 case "*": case "/": while (!stack.empty()&&(stack.peek().equals("*") || stack.peek().equals("/"))) list.add(stack.pop()); stack.push(c); break; //0-9 处理 default: int num= Integer.parseInt(c); while (i<s.length()-1&& Character.isDigit(s.charAt(i+1))){ num=num*10+s.charAt(i+1)-'0'; i++; } list.add(String.valueOf(num)); } } while (!stack.empty()) list.add(stack.pop()); return list; } private static double calculate(List<String> list) { Stack<Double> stack = new Stack<>(); for (String s : list) { switch (s) { case "+": stack.push(stack.pop() + stack.pop()); break; case "-": double first = stack.pop(); double second = stack.pop(); stack.push(second - first); break; case "*": stack.push(stack.pop() * stack.pop()); break; case "/": double first1 = stack.pop(); double second1 = stack.pop(); stack.push(second1 / first1); break; // num default: stack.push(Double.parseDouble(s)); } } return stack.pop(); } }
#include<iostream> #include<string> #include<stack> #include<iomanip> using namespace std; char str[220]; bool ret; int pos; int mag[][5] { 1,0,0,0,0, 1,0,0,0,0, 1,0,0,0,0, 1,1,1,0,0, 1,1,1,0,0, }; stack<int>op; stack<double>num; void get(int& pos, bool& ret, int& i) { if (i == 0 && op.empty() == true) { ret = true; pos = 0; return; } if (str[i] == 0) { ret = true; pos = 0; return; } if (str[i] >= '0' && str[i] <= '9') { ret = false; pos = 0; for (; str[i] != ' ' && str[i] != 0; i++) { pos = pos * 10 + str[i] - '0'; } if (str[i] == ' ') i++; return; } else { ret = true; if (str[i] == '+') { pos = 1; } else if (str[i] == '-') { pos = 2; } else if (str[i] == '*') { pos = 3; } else if (str[i] == '/') { pos = 4; } i += 2; return; } } int main() { while (cin.getline(str, 220)) { if (str[0] == '0' && str[1] == 0)break; int pos, idx = 0; bool ret; while (!op.empty())op.pop(); while (!num.empty())num.pop(); while (true) { get(pos, ret, idx); if (ret == false) num.push((double)pos); else { double temp; if (op.empty() == true || mag[pos][op.top()] == 1) op.push(pos); else { while (mag[pos][op.top()] == 0) { int t = op.top(); op.pop(); double b = num.top(); num.pop(); double a = num.top(); num.pop(); switch (t) { case 1:temp = a + b; break; case 2:temp = a - b; break; case 3:temp = a * b; break; case 4:temp = a / b; break; default :break; } num.push(temp); } op.push(pos); } } if (op.size() == 2 && op.top() == 0) break; } cout <<fixed <<setprecision(2) << num.top() << endl; } return 0; }
这不是最好的写法,但是让想到了编译原理的递归下降分析,纯c写得比较繁琐见谅
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
double parseExpression();
double parseTerm();
double parseFactor();
double parseExpression() {
double left=parseTerm();
char op, c;
while((op=getchar())==' ');
if(op=='+'||op=='-') {
while(op=='+'||op=='-') {
while((c=getchar())==' '); ungetc(c, stdin);
double right=parseTerm();
if(op=='+') left+=right;
else left-=right;
while((op=getchar())==' ');
}
}
return left;
}
double parseTerm() {
double left=parseFactor();
char op, c;
while((op=getchar())==' ');
if(op=='*'||op=='/') {
while(op=='*'||op=='/') {
while((c=getchar())==' '); ungetc(c, stdin);
double right=parseFactor();
if(op=='*') left*=right;
else left/=right;
while((op=getchar())==' ');
}
}
ungetc(op, stdin);
return left;
}
double parseFactor() {
int x;
scanf("%d", &x);
return (double)x;
}
int main()
{
char c;
while((c=getchar())!=EOF) {
if(c=='0') break; /* this is cursory though */
else {
ungetc(c, stdin);
printf("%.2f\n", parseExpression());
}
}
return 0;
}
#include<stdio.h> int main(){ int tmp; char ch; while(scanf("%d%c",&tmp,&ch)!=EOF){ if(tmp==0&&ch=='\n') continue; double ans[210]={0},sum=0; ans[0]=tmp; int size=0; while(scanf("%c",&ch)!=EOF){ scanf("%d",&tmp); switch(ch){ case '+':ans[++size]=tmp;break; case '-':ans[++size]=-tmp;break; case '*':ans[size]*=tmp;break; case '/':ans[size]/=tmp;break; } getchar(); } for(int i=0;i<=size;i++) sum+=ans[i]; printf("%.2lf\n",sum); } }
#include <stdio.h> #include <string.h> #include <stack> #define N 300 using namespace std; stack<char> op;//栈,存储运算符 stack<double> data;//栈,存储数据 char str[N];//用来存用户输入的字符串 void Clear()//清空数据栈和运算符栈 { while(!op.empty()) op.pop(); while(!data.empty()) data.pop(); } int Priority(char c)//判断运算符优先级 { if(c=='+' || c=='-') return 1; else if(c=='*' || c=='/') return 2; else return 0;//如果是'#'则优先级为0 } void GetNum(int &x, int &i)//读取字符串中的数字,x为数值,i为字符串下标 { x=0; while(str[i]!=' '&&str[i]!='\0') { x=x*10+(str[i]-'0'); i++; } if(str[i]==' ') i++; } void CalOnce() {//取两个数、一个运算符,运算结果存入data栈 if(data.size()<2) return;//没那么多数就别算了(貌似用不到?) double b=data.top(); data.pop(); double a=data.top(); data.pop(); switch(op.top()) { case '+': data.push(a+b); break; case '-': data.push(a-b); break; case '*': data.push(a*b); break; case '/': data.push(a/b); break; } op.pop(); return; } void Calculate() {//根据字符串进行运算,并输出结果 int x, i=0;//从头开始分析字符串 int len=strlen(str); Clear();//清空运算符栈和数据栈 op.push('#');//#用来标记开始,其优先级为0 while(i<len) { if('0'<=str[i]&&str[i]<='9')//碰到数字直接压入数据栈 { GetNum(x, i); data.push((double)x); } else//碰到了运算符的话 { if(Priority(str[i])>Priority(op.top())) op.push(str[i]); //优先级较高就直接压入运算符栈 else{//优先级不高于栈顶运算符的话 while(Priority(str[i])<=Priority(op.top())) {//不停运算直到可以压入 CalOnce(); } op.push(str[i]);//压入运算符 } i+=2;//跳过这个运算符顺便跳过空格 } } while(Priority(op.top())!=0) CalOnce(); //最后输入的数没处理,处理一下,假装输入了一个优先级很低的运算符 printf("%.2lf\n", data.top());//输出结果 } int main() { while(gets(str)) { if(strcmp("0", str)==0) break; Calculate();//计算并输出结果 } return 0; }
//参考楼上@苏合杭写的C++版本,注意cin和scanf的区别 #include<iostream> using namespace std; const int maxn=201; int main() { double temp,ans[maxn]; char ch; while(cin>>temp&&temp) { int num=0; double sum=0; ans[num]=temp; while(cin>>ch>>temp) { switch(ch) { case '+':ans[++num]=temp; break; case '-':ans[++num]=-temp; break; case '*':ans[num]*=temp; break; case '/':ans[num]/=temp; break; } char c=cin.get(); if(c=='\n') break; } for(int i=0;i<=num;i++) sum+=ans[i]; printf("%0.2f\n",sum); } return 0; }
#include<iostream> using namespace std; #include<string> #include<vector> #include<stack> #include<iomanip> /*读入一个只包含 +, -, *, / 的 非负整数 计算表达式,计算该表达式的值*/ int precedence(char op)//计算运算符优先级 { switch (op) { case '*': case '/': return 2; case '+': case '-': return 1; case '@': default: return 0; } } void cal(char temp,stack<double> &num) { double x = 0; switch (temp) { case '+': { x = num.top(); num.pop(); x += num.top(); num.pop(); num.push(x); break; } case '-': { x = num.top(); num.pop(); x = num.top() - x; num.pop(); num.push(x); break; } case '*': { x = num.top(); num.pop(); x *= num.top(); num.pop(); num.push(x); break; } case '/': { x = num.top(); num.pop(); if (x == 0) { cout << "除数为零" << endl; exit(1); } else { x = num.top() / x; num.pop(); num.push(x); } break; } default: break; } } double calculateValue(string str) { stack<char> op; stack<double> num; op.push('@'); char ch; int i = 0; while (i!=str.size()) { ch = str[i]; if (ch == ' ') { i++; continue; } else if(ch == '+' || ch == '-' || ch == '*' || ch == '/') { char temp = op.top(); while (precedence(ch) <= precedence(temp)) { cal(temp, num); op.pop(); temp = op.top(); } op.push(ch); i++; } else//数字 { int y = 0; while (str[i] >= '0' && str[i] <= '9') { y = y * 10 + str[i] - '0'; i++; } num.push(y); } } while (op.top() != '@') { cal(op.top(), num); op.pop(); } return num.top(); } int main() { vector<string> expression; string str; while (getline(cin,str)) { if (str == "0") break; expression.push_back(str); } for (int i = 0; i < expression.size(); i++) cout << setiosflags(ios::fixed)<<setprecision(2) <<calculateValue(expression[i]) << endl; return 0; }
#include <stdio.h> #include <string.h> #define MAX 205 /* 这道题目主要采用栈来求解 为了锻炼使用语言解决问题的能力,这里通过数组来模拟栈 */ struct Node { double num; char op; int flag; }; struct Node Stack[MAX];//符号栈 struct Node Queue[MAX];//用来存放后缀表达式 char str1[MAX]; char str2[MAX]; int op[256]; //将中缀表达式转化为后缀表达式 int Change(int length) { double num; struct Node temp; int i; int cnt=0; int top=0; for(i=0;i<length;) { //如果是操作数 if(str2[i]>='0'&&str2[i]<='9') { temp.flag=1; temp.num=0; while(str2[i]!='\0'&&str2[i]>='0'&&str2[i]<='9') { temp.num=temp.num*10+str2[i]-'0'; i++; } Queue[cnt++]=temp; } //如果是运算符,则需要先比较运算符与当前栈顶符号的优先级 //如果栈顶符号优先级更高,则要加入到队列数组当中 //如果优先级较低的话,则将符号压入到符号栈当中 else { temp.flag=0; while(top!=0&&op[str2[i]]<=op[Stack[top-1].op])//这里注意栈顶指针等于栈顶位置+1 { Queue[cnt++]=Stack[--top]; } temp.op=str2[i]; Stack[top++]=temp; i++; } } while(top!=0)//清空栈,构造完整的后缀表达式 { Queue[cnt++]=Stack[--top]; } return cnt; } double Cal(int cnt)//计算后缀表达式 { double temp1,temp2; struct Node cur,temp; int top=0; int i,j; for(i=0;i<cnt;i++) { cur=Queue[i]; if(cur.flag==1) Stack[top++]=cur; else { //特别注意top必须加入前缀--,因为top指针总是等于栈顶元素位置+1 temp2=Stack[--top].num;//操作数2 temp1=Stack[--top].num;//操作数1 temp.flag=1; if(cur.op=='+') temp.num=temp1+temp2; else if(cur.op=='-') temp.num=temp1-temp2; else if(cur.op=='*') temp.num=temp1*temp2; else temp.num=temp1/temp2; Stack[top++]=temp; } } return Stack[top-1].num; } int main() { op['+']=op['-']=1; op['*']=op['/']=2; while(fgets(str1,205,stdin)&&strcmp(str1,"0\n")!=0) { int len=strlen(str1); int i,j=0; for(i=0;i<len;i++) { if(str1[i]==' '||str1[i]=='\n') continue; else str2[j++]=str1[i]; } str2[j]='\0'; int cnt=Change(j); printf("%.2f\n",Cal(cnt)); } return 0; }
#include <stdio.h> #include <string.h> int main(){ char s[200]; int i,j,len; float sum,tmp; while(gets(s)){ if(!strcmp(s,"0")) break; len = strlen(s); float a[201]={0}; tmp=0; i=0; while(s[i]>='0'&&s[i]<='9'){ tmp*=10; tmp+=s[i]-'0'; i++; } a[0]=tmp; for(j=0;i<len;i++){ if(s[i]=='+'){ tmp=0; i+=2; while(s[i]>='0'&&s[i]<='9'){ tmp*=10; tmp+=s[i]-'0'; i++; } a[++j]=tmp; } else if(s[i]=='-'){ tmp=0; i+=2; while(s[i]>='0'&&s[i]<='9'){ tmp*=10; tmp+=s[i]-'0'; i++; } a[++j]=-tmp; } else if(s[i]=='*') { tmp=0; i+=2; while(s[i]>='0'&&s[i]<='9'){ tmp*=10; tmp+=s[i]-'0'; i++; } a[j]*=tmp; } else if(s[i]=='/') { tmp=0; i+=2; while(s[i]>='0'&&s[i]<='9'){ tmp*=10; tmp+=s[i]-'0'; i++; } a[j]/=tmp; } } for(i=0,sum=0;i<=j;i++) sum+=a[i]; printf("%.2f\n",sum); } }
#include <iostream> #include <stack> #include <cstdio> #include <cctype> #include <string> using namespace std; int pri (char ch){//返回字符优先级 int p=-1; if(ch=='#') p=0; else if(ch=='$') p=1; else if(ch=='+'||ch=='-') p=2; else p=3; return p; } double getNumber(string s, int& index){//返回字符串当前下标到下一个空格间的数字 double ans=0; while(isdigit(s[index])){ ans*=10; ans+=s[index]-'0'; index++; } return ans; } double cal (double x, double y, char ch){//返回字符优先级 double result=0; if(ch=='+') result=x+y; else if(ch=='-') result=x-y; else if(ch=='*') result=x*y; else if(ch=='/') result=x/y; return result; } int main(){ string str; while(getline(cin,str,'\n') && str!="0"){ int index=0; stack<double>num; stack<char>op; str+='$'; op.push('#'); while(index<str.length()){ if(str[index]==' '){ index++; } else if(isdigit(str[index])){ num.push(getNumber(str, index)); } else{ if(pri(str[index])>pri(op.top())){//如果当前字符比栈顶字符的优先级高,则进栈 op.push(str[index]); index++; } else{//如果当前字符比栈顶字符的优先级低,则计算栈里的 //数字的顺序别弄反了 double y = num.top(); num.pop(); double x = num.top(); num.pop(); char ch = op.top(); num.push(cal(x,y,ch));//结果再放入栈 op.pop(); } } } printf("%.2f\n",num.top()); } return 0; }
#include <cstdio> int main(){ double term = 0; char ch; while(scanf("%lf%c", &term, &ch) != EOF){ double result = 0; if(term == 0.0 && ch == '\n') return 0; while(scanf("%c", &ch) != EOF){ printf("op is %c\n", ch); int temp; scanf(" %d", &temp); switch(ch) { case '+': { result += term; term = temp; break; } case '-': { result += term; term = -temp; break; } case '*': { term *= temp; break; } case '/': { term /= temp; break; } default: { printf("*** up!\n"); } } char space = getchar(); if(space == '\n') break; } printf("%.2lf\n", term + result); //最后一项和之前所有项的和。 } }
#include <cstdio> #include <string> #include <stack> #include <map> using namespace std; //表达式求值 int main() { char buf[300]; //优先级 map<char, int> priority = { {'$', 0}, {'+', 1},{'-', 1}, {'*', 2},{'/', 2} }; while (fgets(buf, 300, stdin) != NULL) { string expr = buf; expr.pop_back(); //将末尾的换行符弹出 if (expr == "0") { //为 0 则结束 break; } expr.push_back('$');//补充一个虚拟的终止符 string num; //用来收集单独的0-9以组成数字:1 2 3 4 ——> 1234 stack<double> numstack; stack<char> operstack; for (int i = 0; i < expr.size(); i++) { if (expr[i] >= '0' && expr[i] <= '9') { num.push_back(expr[i]); } //如果是空格,说明数字拼好了 else if (expr[i] == ' ') { if (num != "") { //stod --> string to double numstack.push(stod(num)); //将num重新设置为空 num = ""; } } // + - * / $ else { if (expr[i] == '$') { if (num != "") { numstack.push(stod(num)); num = ""; } } //当符号栈非空 && 栈内优先级 >= 当前符号优先级时 while (!operstack.empty() && priority[operstack.top()] >= priority[expr[i]]) { double right = numstack.top(); //右操作数 numstack.pop(); double left = numstack.top(); //左操作数 numstack.pop(); char oper = operstack.top(); //运算符 operstack.pop(); switch (oper) { case '+': numstack.push(left + right); break; case '-': numstack.push(left - right); break; case '*': numstack.push(left * right); break; case '/': numstack.push(left / right); break; } } //所有比expr[i]优先级更高的运算符都计算过了 operstack.push(expr[i]); } } //输出最终结果 printf("%.2lf\n", numstack.top()); } }