测试输入包含若干测试用例,每个测试用例占一行,每行不超过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;
} #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 <bits/stdc++.h>
using namespace std;
const double N = 1000010;
stack<double> num; // 数字栈
stack<char> op; // 运算符栈
unordered_map<char, int> k{
{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}
};
// 执行计算
void eval() {
double a = num.top();
num.pop(); // 获取栈顶数字
double b = num.top();
num.pop(); // 获取栈顶的另一个数字
char c = op.top();
op.pop(); // 获取栈顶运算符
double res = 0;
if (c == '+') res = b + a;
if (c == '-') res = b - a;
if (c == '*') res = b * a;
if (c == '/') res = b / a;
num.push(res); // 将结果压入数字栈
}
int main() {
string s;
while (getline(cin, s) && s != "0") { // 读取每行直到输入为"0"
for (int i = 0; i < s.size(); i++) {
// 跳过空格
if (s[i] == ' ') continue;
// 处理数字
if (isdigit(s[i])) {
double x = 0;
while (i < s.size() && isdigit(s[i])) { // 处理多位数字
x = x * 10 + (s[i] - '0');
i++;
}
num.push(x);
i--; // 回退一个位置,以便下一轮循环继续处理
}
// 处理运算符
else {
// 当栈顶运算符的优先级大于或等于当前运算符时,执行运算
while (op.size() && k[op.top()] >= k[s[i]]) {
eval();
}
op.push(s[i]);
}
}
// 最终处理栈中剩余的运算符
while (op.size()) eval();
// 输出结果,保留两位小数
printf("%.2f\n", num.top());
num.pop(); // 清空数字栈
}
}
#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());
}
}