首页 > 试题广场 >

计算表达式

[编程题]计算表达式
  • 热度指数:24721 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
对于一个不存在括号的表达式进行计算

输入描述:
存在多组数据,每组数据一行,表达式不存在空格


输出描述:
输出结果
示例1

输入

6/2+3+3*4

输出

18
我来提供一个递归的方法,有括号也可以用,将表达式看成由 + ,- 号连接的项组成,项再看成由 * , / 号连接的因子组成。
#include <iostream>
using namespace std;

float expression_value();

float factor_value() {			//读入一个因子并返回它的值
	float result = 0;
	char c = cin.peek();
	if (c == '(') {
		cin.get();					//取走左括号
		result = expression_value();
		cin.get();					//取走右括号
	}
	else {
		while (isdigit(c)) {
			result = 10 * result + c - '0';
			cin.get();
			c = cin.peek();
		}
	}
	return result;
}

float term_value() {				//读入一项并返回它的值
	float result = factor_value();
	while (true) {
		char op = cin.peek();
		if (op == '*' || op == '/') {
			cin.get();
			float value = factor_value();
			if (op == '*') result *= value;
			else result /= value;
		}
		else break;
	}
	return result;
}

float expression_value() {		//求一个表达式值
	float result = term_value();	//求第一项的值
	bool more = true;
	while (more) {
		char op = cin.peek();	//cin.peek()看输入流中第一个字符,且不将其取出
		if (op == '+' || op == '-') {
			cin.get();			//cin.get()取走输入流第一个字符
			float value = term_value();
			if (op == '+') result += value;
			else result -= value;
		}
		else more = false;
	}
	return result;
}

int main()
{
	cout << expression_value() << endl;
}


发表于 2021-03-02 22:01:15 回复(0)
支持加减乘除乘方 负数 括号 浮点数 
#include<iostream> #include<string> #include<map> #include<stack> #include<cmath> #include<cstdlib>
using namespace std;
bool isnum(char c) {  return (c>='0'&&c<='9'); }
map<char,int> pri; stack<char> ops; stack<double> nums;
double calculate(double a, char op, double b) {  switch(op)  {   case '+':    return a+b;   case '-':    return a-b;   case '*':    return a*b;   case '/':    return a/b;   case '^':    return pow(a,b);   default:    return 0;  } }
void do_calculate() {  double a=nums.top();  nums.pop();  double b=nums.top();  nums.pop();  char op = ops.top();  ops.pop();  nums.push(calculate(b,op,a)); //注意b在前面 }
int main() {  pri.insert(pair<char,int>('+',1));  pri.insert(pair<char,int>('-',1));  pri.insert(pair<char,int>('*',2));  pri.insert(pair<char,int>('/',2));  pri.insert(pair<char,int>('^',3));  string in;  while(cin>>in)  {   while(!ops.empty()) ops.pop();   while(!nums.empty()) nums.pop();   for(int i=0;i<in.size();i++)   {    if(isnum(in[i]))    {     string tmp;     tmp.push_back(in[i++]);     while(isnum(in[i])||in[i]=='.')     {      tmp.push_back(in[i++]);     }     i--; //抵消for循环的i++     nums.push(atof(tmp.c_str()));     //atof只接受char*参数,用c_str把string转换成char*,atof在头文件cstdlib里    }    else    {     if(in[i]=='-'&&(nums.empty()||!isnum(in[i-1]))) //注意先判断nums是不是空,否则如果第一个是-in[i-1]数组越界     {      i++;      string tmp;      while(isnum(in[i])||in[i]=='.')      {       tmp.push_back(in[i++]);      }      i--;      nums.push(-atof(tmp.c_str()));     }     else if(ops.empty())     {      ops.push(in[i]);     }     else if(in[i]=='(')     {      ops.push(in[i]);      }     else if(in[i]==')')     {      while(ops.top()!='(')      {       do_calculate();      }      ops.pop(); //弹出(     }     else if(pri[in[i]]>pri[ops.top()])     {      ops.push(in[i]);     }     else if(pri[in[i]]<=pri[ops.top()]) //注意,等于的时候也得计算,不能入栈,不然类似1-1-1的计算就会变成1     {      do_calculate(); //计算一次之后,可能in[i]优先级还是不大于栈顶的优先级,所以继续把in[i]和新栈顶比较      i--; //再次将in[i]和栈里面的符号对比,直到栈空或者符号优先级大于栈顶     }    }   }   while(!ops.empty())   {    do_calculate();   }   cout<<nums.top()<<endl;  } }

编辑于 2018-06-13 20:30:09 回复(0)
from __future__ import division
try:
    while 1:
        print int(input())
except:
    pass

发表于 2016-12-28 13:52:49 回复(0)
//不得不说,没有理解scanf还可以这么用,让这个问题瞬间简单下来,参考了网上的代码
#include<cstdio>
#include<iostream>
using namespace std;
int main(){
   double t;
     double a[1000];
    while(scanf("%lf",&t)!=EOF){
        double sum=0;
        char ch;int i=0;a[0]=t;
        while(scanf("%c",&ch)!=EOF&&ch!='\n'){
            double tem;
            scanf("%lf",&tem);
            if(ch=='+') 
                a[++i]=tem;
            else if(ch=='-')
                a[++i]=-tem;
            else if(ch=='*')
                a[i]*=tem;
            else if(ch=='/')
                a[i]/=tem;
        }
        for(int j=0;j<=i;j++)
            sum+=a[j];
        cout<<sum<<endl;
    }
    
    
    
    
}
发表于 2017-06-09 20:54:25 回复(9)

python one line solution:


while True:
    try:
        print(int(eval(input())))
    except:
        break
发表于 2017-10-01 17:27:40 回复(1)
#include<iostream>
using namespace std;
int main() {
 double val[1010];
 while (~scanf("%lf", &val[0])) {
  char op;
  int ai = 0;
  double nex;
  while (~scanf("%c", &op) && op != '\n') {
   scanf("%lf", &nex);
   switch (op) {
   case '+':val[++ai] = nex; break;
   case '-':val[++ai] = -nex; break;
   case '*':val[ai] *= nex; break;
   case '/':val[ai] /= nex; break;
   }
  }
  double res=0;
  for (int i = 0; i <= ai; ++i)
   res += val[i];
  cout << res << endl;
 }
 return 0;
}

发表于 2017-08-16 15:44:11 回复(0)
#include<iostream>
#include<stack>
using namespace std;

int main()
{
	stack<float> st;
	float num,ans;
	char c;
	cin >> num;
	st.push(num);
	while (cin.peek()!='\n')
	{
		cin >> c >> num;
		if (c == '-')
			num = -num;
		if (c == '*')
		{
			num *= st.top();
			st.pop();
		}
		if (c == '/')
		{
			num=st.top()/num;
			st.pop();
		}
		st.push(num);
	}
	ans = 0;
	while (!st.empty())
	{
		ans += st.top();
		st.pop();
	}
	cout << ans << endl;
}


编辑于 2021-01-23 19:46:24 回复(0)
虽然python有内置函数直接算,但还是挑战一下,输出为整数
把结果保存为一个栈,最后所有数相加,
加法直接压栈,减法压栈相反数,乘法取出一个数相乘后压栈,除法取出一个数相除后压栈
while True:
    try:
        string = list(input())
        result,lastSign,temp = [],'+',''   #保存上一个符号
        while string:
            if string[0].isdigit():
                temp += string[0]
            else:
                if lastSign == '+':
                    result.append(float(temp))
                elif lastSign == '-':
                    result.append(-float(temp))
                elif lastSign == '*':
                    left = result.pop()
                    result.append(left*float(temp))
                elif lastSign == '/':
                    left = result.pop()
                    result.append(left/float(temp))
                lastSign = string[0]
                temp = ''                #如果当前为符号,那么计算后数字置空
            string.pop(0)
        if lastSign == '+':
            result.append(float(temp))
        elif lastSign == '-':
            result.append(-float(temp))
        elif lastSign == '*':
            left = result.pop()
            result.append(left * float(temp))
        elif lastSign == '/':
            left = result.pop()
            result.append(left / float(temp))
        print(int(sum(result)))
    except Exception:
        break
编辑于 2018-10-13 23:47:51 回复(0)
//本代码也考虑了带括号的表达式计算
#include<string>
#include<iostream>
#include<stack>
#include<vector>
#include<sstream>
using namespace std;
float operation(float a,string op,float b){
    if(op=="+"){
        return a+b;
    }else if(op=="-"){
        return a-b;
    }else if(op=="*"){
        return a*b;
    }else{
        return a/b;
    }
}
bool op_prior(string a, string b){  //定义运算符号的优先级,“+”“-”——1 , “*”“/”——2 
    int aa,bb;
    if(a=="+"||a=="-"){
        aa=1;
    }else if(a=="*"||a=="/"){
        aa=2;
    }
    if(b=="+"||b=="-"){
        bb=1;
    }else if(b=="*"||b=="/"){
        bb=2;
    }
    return aa>=bb;
}
bool judge(char c){
    if(c>='0'&&c<='9') return true;
    return false;
}
int main(){
    string str;  //表达式不存在空格
    while(cin>>str){
        vector<string> inStr;
        vector<string> postStr;  //存储后缀表达式
        stack<string> opStack;
        //将中缀表达式转换为后缀表达式
        int len = str.size();
        string ans;
        for(int i=0;i<len;i++){
            if(judge(str[i])){
                ans += str[i];
                if(i+1<len && judge(str[i+1])){
                    
                }else{
                    inStr.push_back(ans);
                    ans.clear();
                }
            }else{
                ans += str[i];
                inStr.push_back(ans);
                ans.clear();
            }
        }
        int size = inStr.size();
        for(int i=0;i<size;i++){
            if(inStr[i]=="("){
                opStack.push(inStr[i]);
            }else if(inStr[i]==")"){  //去匹配'('
                while(!opStack.empty()){
                    string topc = opStack.top();
                    opStack.pop();
                    if(topc=="("){
                        break;
                    }else{
                        postStr.push_back(topc);
                    }
                }
            }else if(inStr[i]=="+"||inStr[i]=="-"||inStr[i]=="*"||inStr[i]=="/"){ //为运算符,入栈
                if(opStack.empty()){
                    opStack.push(inStr[i]);
                }else{
                    while(!opStack.empty()){
                        string topc = opStack.top();
                        if(topc=="(") break;
                        if(op_prior(topc,inStr[i])){
                            postStr.push_back(topc);
                            opStack.pop();
                        }else{
                            break;
                        }
                    }
                    opStack.push(inStr[i]);
                }
            }else{ //数字
                postStr.push_back(inStr[i]);
            }
        }
        //剩下的全部出栈
        while(!opStack.empty()){
            postStr.push_back(opStack.top());
            opStack.pop();
        }
        //对后缀表达式进行计算(对数字进行入栈)
        size = postStr.size();
        stack<float> numStack;  //除法可能产生小数,所以用float型
        stringstream ss;
        for(int i=0;i<size;i++){
            if(postStr[i]=="+"||postStr[i]=="-"||postStr[i]=="*"||postStr[i]=="/"){//运算符(后缀表达式肯定不含括号了)
                float n2 = numStack.top();
                numStack.pop();
                float n1 = numStack.top();
                numStack.pop();
                float res = operation(n1,postStr[i],n2);
                numStack.push(res);
            }else{
                ss<<postStr[i];
                float val;
                ss>>val;
                numStack.push(val);
                ss.clear();
            }
        }
        cout<<numStack.top()<<endl;;
        
    }
    return 0;
}

发表于 2016-06-26 16:23:37 回复(1)
根据自己“简单计算器”这一题的答案改编

#include <stdio.h>
#include <string.h>

int main(){
    char s[200];
    int i,j,len;
    float sum,tmp;
    while(gets(s)){
        len = strlen(s);
        float a[100]={0};
        tmp=0;
        i=0;
        while(s[i]>='0'&&s[i]<='9'){
                    tmp*=10;
                    tmp+=s[i]-'0';
                    i++;
        }        
        a[0]=tmp;
        j=0;
        while(i<len){
            if(s[i]=='+'){
                tmp=0;
                i++;
                while(s[i]>='0'&&s[i]<='9'){
                    tmp*=10;
                    tmp+=s[i]-'0';
                    i++;
                }
                 a[++j]=tmp;
            }
            else if(s[i]=='-'){
                tmp=0;
                i++;
                while(s[i]>='0'&&s[i]<='9'){
                    tmp*=10;
                    tmp+=s[i]-'0';
                    i++;
                }
                 a[++j]=-tmp;                
            } 
            else if(s[i]=='*') {
                tmp=0;
                i++;
                while(s[i]>='0'&&s[i]<='9'){
                    tmp*=10;
                    tmp+=s[i]-'0';
                    i++;
                }
                a[j]*=tmp;
            }
            else if(s[i]=='/') {
                tmp=0;
                i++;
                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("%d\n",(int)sum);
    }
}

加油(•̀ᴗ•́)و

发表于 2021-02-03 21:41:19 回复(1)
print(int(eval(input())))
发表于 2025-03-03 11:35:14 回复(1)
#include <iostream>
using namespace std;
#include <stack>
int getLevel(char c){//计算符号的优先级
    if(c=='+'||c=='-'){
        return 2;
    }
    else if(c=='*'||c=='/'){
        return 3;
    }else if(c=='$'){
        return 1;//$的优先级一定要小于运算符,这样才能保证$之前的符号全部都能参加运算
    }else return 0;//这里其实对应的是符号栈底'#'的优先级,即当符号栈为只剩下'#'的时候 ‘$’才能进入符号栈
}
double caculate(double x,double y,char op){
    if(op=='+')
    return x+y;
    else if(op=='-')
    return y-x;
    else if(op=='*')
    return x*y;
    else 
    return y/x;
}
int main() {
    stack<char>op; op.push('#');//符号栈底部从'#'开始
    stack<double>num;
    string str;
    while(cin>>str){
        str+='$';//输入的表达式末尾添加一个'$',以便之前的都能参与计算
        int temp;
        for(int i=0;i<str.size();i++){
            if(str[i]>='0'&& str[i]<='9'){//如果是数字就不断
                temp = temp*10 + str[i]-'0';//乘10再相加
            }else{  //当扫描到符号时                        
                if(temp!=0){
                    num.push(temp);//把之前累计的数字加入数字栈
                    temp=0;//别忘了清空temp
                }
                if(getLevel(str[i])>getLevel(op.top())){
                    op.push(str[i]);//如果新的符号优先级大于栈顶的优先级就加入符号栈
                }else{
                    while(getLevel(str[i])<=getLevel(op.top())){//当新的符号优先级小于等于栈顶的优先级 就从数字栈弹出两个数,符号栈弹出一个符号并计算数值,再压回数字栈顶。
                        double x= num.top();
                        num.pop();
                        double y= num.top();
                        num.pop();
                        num.push(caculate(x,y,op.top())); op.pop();
                    }
                    op.push(str[i]);//直到当前扫描到的符号优先级大于栈顶符号优先级的时候,把当前符号压入符号栈顶
                }
            }
        }
        cout<<num.top();
    }
}

发表于 2025-02-08 20:43:39 回复(1)
#include<stdio.h>//1.符号数字分开//2.进行乘除运算然后循环前移
int main()//3.进行加减运算
{
    char a[100],fuhao[50];
    int i,j,num=0;float shuzi[50]={0},sum=0;
    gets(a);
    for(i=0;a[i]!='\0';i++)//数字0-num,符号0-num-1
    {
        if(a[i]>='0'&&a[i]<='9')
            shuzi[num]=shuzi[num]*10+(a[i]-'0');//注意可能很多位一个数字
        else
        { fuhao[num]=a[i]; num++; }
    }
    //乘除运算
    for(i=0;i<num;i++)
    {
        if(fuhao[i]=='*')
        {
            shuzi[i]=shuzi[i]*shuzi[i+1];
            for(j=i+1;j<=num;j++)//数字前移
                shuzi[j]=shuzi[j+1];
            for(j=i;j<num;j++)//符号前移
                fuhao[j]=fuhao[j+1];
            num--;i--;//长度减一,从当前位置重新开始
        }
        if(fuhao[i]=='/')
        {
            shuzi[i]=shuzi[i]/shuzi[i+1];
            for(j=i+1;j<=num;j++)//数字前移
                shuzi[j]=shuzi[j+1];
            for(j=i;j<num;j++)//符号前移
                fuhao[j]=fuhao[j+1];
            num--;i--;//长度减一,从当前位置重新开始
        }
    }
    sum=shuzi[0];//加减运算
    for(i=0;i<num;i++)
    {
        if(fuhao[i]=='+')
            sum+=shuzi[i+1];
        if(fuhao[i]=='-')
            sum-=shuzi[i+1];
    }
    printf("%.0f",sum);
}

发表于 2020-04-20 13:03:32 回复(0)
既然python有内置函数,那么就不必去操心了
print(int(eval(input())))

发表于 2020-03-24 19:25:12 回复(0)
#include <iostream>
#include <stack>
#include <string>
using namespace std;

int calculate(string s) {
    stack<double> stk;
    double curNum = 0.0;
    char prevOp = '+';

    for (int i = 0; i < s.size(); i++) {
        char c = s[i];

        // 累积当前数字(支持多位数字)
        if (isdigit(c)) {
            curNum = curNum * 10 + (c - '0');
        }

        // 遇到非数字或到达末尾时处理前一个运算符
        if (!isdigit(c) || i == s.size() - 1) {
            switch(prevOp) {
                case '+': 
                    stk.push(curNum); 
                    break;
                case '-': 
                    stk.push(-curNum); 
                    break;
                case '*': {
                    double top = stk.top();
                    stk.pop();
                    stk.push(top * curNum);
                    break;
                }
                case '/': {
                    double top = stk.top();
                    stk.pop();
                    stk.push(top / curNum);
                    break;
                }
            }
            prevOp = c;  // 更新运算符
            curNum = 0.0; // 重置当前数字
        }
    }

    double result = 0.0;
    while (!stk.empty()) {
        result += stk.top();
        stk.pop();
    }

    return (int)result;  // 最终输出整数结果
}

int main() {
    string expr;
    while (cin >> expr) {
        cout << calculate(expr) << endl;
    }
    return 0;
}

发表于 2025-03-12 13:46:18 回复(0)
#include <math.h>
#include<stdio.h>
#include<string.h>

#pragma warning(disable:4996)        //关闭全部
#define N 1000
#define M 100

int shuzi(char* zifu, int i);

int main() {

    char zifu[N] = { 0 };
    scanf("%s", zifu);

    double tmp[100] = { 0 };
    int j = 0;              //指向tmp里的数字指针
    int i = 0;              //指向zifu里的数字指针
    while ( i < strlen(zifu)) {

        //第一次遇到数字
        if (zifu[i] >= '0' && zifu[i] <= '9') {
            tmp[j] = shuzi(zifu, i);
            j++;
            while (zifu[i] >= '0' && zifu[i] <= '9') {
                i++;
            }
        }

        //遇到加号
        else if (zifu[i] == '+') {
            i++;
            tmp[j] = shuzi(zifu, i);
            j++;
            while (zifu[i] >= '0' && zifu[i] <= '9') {
                i++;
            }
        }

        //遇到减号
        else if (zifu[i] == '-') {
            i++;
            tmp[j] = shuzi(zifu, i) * (-1);
            j++;
            while (zifu[i] >= '0' && zifu[i] <= '9') {
                i++;
            }
        }

        //遇到乘号
        else if (zifu[i] == '*') {
            i++;
            int a = shuzi(zifu, i);
            tmp[j - 1] = tmp[j - 1] * a;
            while (zifu[i] >= '0' && zifu[i] <= '9') {
                i++;
            }
        }

        //遇到除号
        else if (zifu[i] == '/') {
            i++;
            int a = shuzi(zifu, i);
            tmp[j - 1] = tmp[j - 1] / a;
            while (zifu[i] >= '0' && zifu[i] <= '9') {
                i++;
            }
        }
    }

    double sum = 0;
    for (int k = 0; k < j; k++) {
        sum += tmp[k];
    }

    int c = (int)sum;
    printf("%d", c);

    getchar();
    return 0;
}
int shuzi(char* zifu, int i) {
    int num = 0;
    while (zifu[i] >= '0' && zifu[i] <= '9') {
        num *= 10;
        num += zifu[i] - '0';
        i++;
    }
    return num;
}
发表于 2024-03-13 21:04:33 回复(0)
#include <iostream>
#include <stack>
#include <string>
#include <map>
using namespace std;

float calculate(float a, float b, char op){
    float res;
    switch (op) {
        case '+': res=a+b;break;
        case '-': res=a-b;break;
        case '*': res=a*b;break;
        case '/': res=a/b;break;
        default: break;
    }
    return res;
}

int main(){
    string input;
    map<char, int> priority = {
            {'$', 0}, {'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}
    };
    while(cin >> input){
        input.push_back('$');
        stack<float> number;
        stack<char> opera;
        string temp;
        float left, right, res = 0;
        char op;
        for(int i=0; i<input.size(); ++i){
            if(input[i]>='0' && input[i]<='9'){
                temp.push_back(input[i]);
            }else{
                number.push(stoi(temp));
                temp = "";
                while(!opera.empty() && priority[opera.top()] >= priority[input[i]]){
                    right = number.top();
                    number.pop();
                    left = number.top();
                    number.pop();
                    op = opera.top();
                    opera.pop();
                    res = calculate(left, right, op);
                    number.push(res);
                }
                opera.push(input[i]);
            }
        }
        cout << number.top() << endl;
    }
}

发表于 2024-03-12 16:18:21 回复(0)
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
#include <stack>

using namespace std;

bool pirority(char c1,char c2)//c1为栈内符号,c2为入栈符号
{
    map<char, int> mp = {{'+',1},{'-',1}, {'*',2}, {'/',2}};

    int p1 = mp[c1];
    int p2 = mp[c2];

    if (p1 < p2)
        return false;//栈内符号优先级小不用弹出
    else
        return true;//栈顶符号弹出
}

double op(double lhs ,double rhs ,char op)
{
    if (op == '+')
        return lhs + rhs;
    else if (op == '-')
        return lhs - rhs;
    else if (op == '*')
        return lhs * rhs;
    else if (op == '/')
        return lhs / rhs;
    else
        return 0;
}

int main()
{
    string str;
    cin >> str;
    stack<char> option;
    stack<double> number;
    string num_s = string();

    for (int i = 0; i < str.size(); ++i)
    {
        //记录字符串中的多位数字,如“123”或者“68”(重要)
        if (str[i] >= '0' && str[i] <= '9')
        {
            num_s += str[i];
        }
        else
        {
            double num_d = stod(num_s);
            num_s = string();//num记录置空
            number.push(num_d);

            while (!option.empty() && pirority(option.top(), str[i]))//while循环是因为可能弹出多次
                //先判断不空,否则栈空的时候option.top()会出错
            {
                char top = option.top();
                option.pop();

                double rhs = number.top();//先弹出右操作数
                number.pop();
                double lhs = number.top();//再弹出左操作数
                number.pop();

                number.push(op(lhs, rhs, top));//算出的数压栈
            }

            if (option.empty() || !(pirority(option.top(), str[i])))//栈空或者栈顶优先级不够弹出
            {
                option.push(str[i]);
            }
        }
    }

    double num_d = stod(num_s);//最后一次循环,最后一个数字没有压栈
    num_s = string();
    number.push(num_d);

    while (!option.empty())//符号栈不空全部弹出(可能剩余一个或者多个)
    {
        char top = option.top();
        option.pop();

        double rhs = number.top();//先弹出右操作数
        number.pop();
        double lhs = number.top();//再弹出左操作数
        number.pop();

        number.push(op(lhs, rhs, top));//算出的数压栈
    }

    double res = number.top();
    number.pop();
    cout << res << endl;    
}
发表于 2024-03-02 10:17:59 回复(0)
#include <iostream>
#include <stack>
#include <string>
using namespace std;

int priority(char c) {  //运算符优先级顺序(# < $ < +- < */)
    switch (c) {
        case '#':
            return 0;
        case '$':
            return 1;
        case '+':
        case '-':
            return 2;
        default:
            return 3;
    }
}

int main() {
    string str;
    while (getline(cin, str)) {
        stack<double>data;  //运算数栈
        stack<char>oprt;    //运算符栈
        int index = 0;      //字符串下标
        str += '$';         //字符串尾部添加'$'
        oprt.push('#');     //运算符栈底添加'#'
        while (index < str.length()) {
            if (isdigit(str[index])) {
                //读取运算数
                double number = 0;
                while (isdigit(str[index])) {
                    number = number * 10 + str[index] - '0';
                    index++;
                }
                data.push(number);
            } else if (priority(oprt.top()) < priority(str[index])) {
                //优先级高的运算符在右,则入栈
                oprt.push(str[index]);
                index++;
            } else {
                //优先级高的运算符在左,则先运算
                //或两个运算符优先级相同,在左的先运算
                double y = data.top();
                data.pop();
                double x = data.top();
                data.pop();
                double result;  //运算结果
                switch (oprt.top()) {
                    case '+':
                        result = x + y;
                        break;
                    case '-':
                        result = x - y;
                        break;
                    case '*':
                        result = x * y;
                        break;
                    case '/':
                        result = x / y;
                }
                data.push(result);  //运算结果入栈
                oprt.pop();
            }
        }
        cout << data.top() << endl;
    }
    return 0;
}

发表于 2024-02-07 00:14:52 回复(0)
题解
//stack <char>  oper 操作符
//stack <double> num 中间数字
//从左向右遍历表达式 1.数字、num压栈 2.运算符 a.高优先级 oper压栈 b.低优先级/相等 先oper弹出一个、再num弹出两个进行运算压回num,
//再把新的运算符压栈

#include <iostream>
#include<cstdio>
#include<map>
#include<stack>
#include<string>
using namespace std;
map<char, int> priority = {
    {'$', 0},
    {'+', 1}, {'-', 1},
    {'*', 2}, {'/', 2}
};
int main() {
    string str;
    while (getline(cin, str)) {

        if (str == "0") {
            break;
        }
        str.push_back('$');//附加结尾符号'$',由于优先级最低,确保所有数值都进行运算
        stack<char>oper;
        stack<double>numb;
        string num;
        for (int i = 0; i < str.size(); ++i) {
            if (str[i] >= '0' &&
                    str[i] <= '9') { //用来搜索单独的0-9以组成一个数
                num.push_back(str[i]);
           if (str[i] != str.size() - 1 && !(str[i + 1] >= '0' && str[i + 1] <= '9'))   // 如果下一个数不是数字
             {
                numb.push(stod(num));//将数值入栈;注释:stod(String TO Double) 将字符串转换为double
                    num = " ";//清空num
                }
                }
                //前面都在处理数
                else {
                while (!oper.empty() &&
                        priority[oper.top()] >=
                        priority[str[i]]) //说明比str[i]优先级更高的运算符都计算过了
                    //新来的运算符的优先级不高于栈顶的优先级
                {
                    char op = oper.top(); //弹出原来的运算符
                    oper.pop();
                    double rhs = numb.top();
                    numb.pop();
                    double lhs = numb.top();
                    numb.pop();//弹出左右两个操作数
                    switch (op) {

                        case'+':
                            numb.push(lhs + rhs);
                            break;
                        case'-':
                            numb.push(lhs - rhs);
                            break;
                        case'*':
                            numb.push(lhs * rhs);
                            break;
                        case'/':
                            numb.push(lhs / rhs);
                            break;
                    }

                }
                oper.push(str[i]);//此时比当前元素符优先级高的都完成了运算,将当前运算符压入栈中
            }
        }
       cout<<numb.top()<<endl;
    }
}


发表于 2024-01-26 10:03:22 回复(0)