【C/C++/Pascal】中缀表达式求值


题目

题目描述

输入一表达式,将其求值后输出。

输入

输入一表达式

输出

输出一个数表示该表达式的值

样例输入

3*(2+5)

样例输出

21

提示

用中缀表达式直接求值。

[C]AC代码

#include<stdio.h>
#include<math.h>
#define maxn 101
int push1(int n,double *p,double v) {
	n++;
	p[n]=v;
	return n;
}
double pop1(int n,double *p) {
	return p[n];
}
int push2(int n,char *p,char v) {
	n++;
	p[n]=v;
	return n;
}
int main() {
	char str[maxn],stackope[maxn],op;
	int nn=0,np=0,i;
	double stacknum[maxn],sec,fir;
	scanf("%s",str);
	for(i=0; str[i]!='@'; i++) {
		if(str[i]>='0'&&str[i]<='9')
			nn=push1(nn,stacknum,(str[i]-'0')*1.00);
		else {
			if(np==0) np=push2(np,stackope,str[i]);
			else if(str[i]=='(') np=push2(np,stackope,str[i]);
			else if(str[i]==stackope[np]) {
				sec=pop1(nn,stacknum);
				nn--;
				fir=pop1(nn,stacknum);
				nn--;
				if(str[i]=='+') {
					nn=push1(nn,stacknum,fir+sec);
				}
				if(str[i]=='-') {
					nn=push1(nn,stacknum,fir-sec);
				}
				if(str[i]=='*') {
					nn=push1(nn,stacknum,fir*sec);
				}
				if(str[i]=='/') {
					nn=push1(nn,stacknum,fir/sec);
				}
			} else if(str[i]=='+') {
				if(stackope[np]=='*') {
					sec=pop1(nn,stacknum);
					nn--;
					fir=pop1(nn,stacknum);
					nn--;
					nn=push1(nn,stacknum,fir*sec);
					np--;
					np=push2(np,stackope,str[i]);
				} else if(stackope[np]=='/') {
					sec=pop1(nn,stacknum);
					nn--;
					fir=pop1(nn,stacknum);
					nn--;
					nn=push1(nn,stacknum,fir/sec);
					np--;
					np=push2(np,stackope,str[i]);
				} else if(stackope[np]=='-') {
					sec=pop1(nn,stacknum);
					nn--;
					fir=pop1(nn,stacknum);
					nn--;
					nn=push1(nn,stacknum,fir-sec);
					np--;
					np=push2(np,stackope,str[i]);
				} else
					np=push2(np,stackope,str[i]);

			} else if(str[i]=='-') {
				if(stackope[np]=='*') {
					sec=pop1(nn,stacknum);
					nn--;
					fir=pop1(nn,stacknum);
					nn--;
					nn=push1(nn,stacknum,fir*sec);
					np--;
					np=push2(np,stackope,str[i]);
				} else if(stackope[np]=='/') {
					sec=pop1(nn,stacknum);
					nn--;
					fir=pop1(nn,stacknum);
					nn--;
					nn=push1(nn,stacknum,fir/sec);
					np--;
					np=push2(np,stackope,str[i]);
				} else if(stackope[np]=='+') {
					sec=pop1(nn,stacknum);
					nn--;
					fir=pop1(nn,stacknum);
					nn--;
					nn=push1(nn,stacknum,fir+sec);
					np--;
					np=push2(np,stackope,str[i]);
				} else
					np=push2(np,stackope,str[i]);
			} else if(str[i]=='*'||str[i]=='/') {
				if(stackope[np]=='*') {
					sec=pop1(nn,stacknum);
					nn--;
					fir=pop1(nn,stacknum);
					nn--;
					nn=push1(nn,stacknum,fir*sec);
					np--;
					np=push2(np,stackope,str[i]);
				} else if(stackope[np]=='/') {
					sec=pop1(nn,stacknum);
					nn--;
					fir=pop1(nn,stacknum);
					nn--;
					nn=push1(nn,stacknum,fir/sec);
					np--;
					np=push2(np,stackope,str[i]);
				} else
					np=push2(np,stackope,str[i]);

			} else if(str[i]=='^') {
				sec=pop1(nn,stacknum);
				nn--;
				nn=push1(nn,stacknum,pow(sec,(str[i+1]-'0')));
				i=i+1;
				continue;
			} else {
				while(stackope[np]!='(') {
					sec=pop1(nn,stacknum);
					nn--;
					fir=pop1(nn,stacknum);
					nn--;
					op=stackope[np];
					if(op=='+') nn=push1(nn,stacknum,fir+sec);
					if(op=='-') nn=push1(nn,stacknum,fir-sec);
					if(op=='*') nn=push1(nn,stacknum,fir*sec);
					if(op=='/') nn=push1(nn,stacknum,fir/sec);
					np--;
				}
				np--;
			}
		}

	}
	while(np!=0) {
		sec=pop1(nn,stacknum);
		nn--;
		fir=pop1(nn,stacknum);
		nn--;
		op=stackope[np];
		if(op=='+') nn=push1(nn,stacknum,fir+sec);
		if(op=='-') nn=push1(nn,stacknum,fir-sec);
		if(op=='*') nn=push1(nn,stacknum,fir*sec);
		if(op=='/') nn=push1(nn,stacknum,fir/sec);
		np--;
	}
	printf("%d",(int)stacknum[nn]);


	return 0;
}

[C++] AC代码

#include <iostream>
#include <stack>
#include <string>
#include <unordered_map>
using namespace std;

stack<int> num;
stack<char> op;

//优先级表
unordered_map<char, int> h{ {'+', 1}, {'-', 1}, {'*',2}, {'/', 2} };


void eval()//求值
{
    int a = num.top();//第二个操作数
    num.pop();

    int b = num.top();//第一个操作数
    num.pop();

    char p = op.top();//运算符
    op.pop();

    int r = 0;//结果 

    //计算结果
    if (p == '+') r = b + a;
    if (p == '-') r = b - a;
    if (p == '*') r = b * a;
    if (p == '/') r = b / a;

    num.push(r);//结果入栈
}

int main()
{
    string s;//读入表达式
    cin >> s;

    for (int i = 0; i < s.size(); i++)
    {
        if (isdigit(s[i]))//数字入栈
        {
            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();//剩余的进行计算
    cout << num.top() << endl;//输出结果
    return 0;
}

[Pascal] AC代码

const
  max=100;
var
  number:array[0..max] of longint;
  symbol:array[1..max] of char;
  s,t:string;
  i,p,j,code:integer;
procedure push;
begin
  inc(p);
  symbol[p]:=s[i];
end;
procedure pop;
begin
  dec(p);
  case symbol[p+1] of
   '+':inc(number[p],number[p+1]);
   '-':dec(number[p],number[p+1]);
   '*':number[p]:=number[p]*number[p+1];
   '/':number[p]:=number[p] div number[p+1];
  end;
end;
function can:boolean;
begin
  can:=true;
  if (s[i] in ['+','-']) and (symbol[p]<>'(')then exit;
  if (s[i] in ['*','/']) and (symbol[p] in ['*','/'])then exit;
   can:=false;
  end;
begin
    readln(s);
    s:=copy(s,1,length(s)-1);
    s:='('+s+')';
    i:=1;
    p:=0;
    while i<=length(s) do
      begin
        while s[i]='(' do
          begin
            push;
            inc(i);
          end;
    j:=i;
    repeat
      inc(i);
      until (s[i]<'0')or(s[i]>'9');
      t:=copy(s,j,i-j);
      val(t,number[p],code);
        repeat
          if s[i]=')' then
            begin
              while symbol[p]<> '(' do pop;
              dec(p);
              number[p]:=number[p+1];
            end
          else
          begin
            while can do
              pop;
              push;
            end;
          inc(i);
          until(i>length(s)) or (s[i-1]<>')');
        end;
      writeln(number[0]);
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值