[蓝桥杯]表达式计算

表达式计算
问题描述
  输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。
输入格式
  输入一行,包含一个表达式。
输出格式
  输出这个表达式的值。
样例输入
1-2+3*(4-5)
样例输出
-4
数据规模和约定
  表达式长度不超过100,表达式运算合法且运算过程都在int内进行。

一、蓝桥杯版本(stack)
#include<iostream>      
#include<cstring>      
#include<stack>      
#include<algorithm>   
#include<cmath>      
using namespace std;      
      
stack<char> s1,s2;      
stack<int> s3;      
char ch[150]={0};//用来存表达式      
int num[11];//用来暂时存数字      
            
int priority(char ch)//用于比较字符优先级      
{      
    if(ch==')') return 1;      
    if(ch=='+'||ch=='-') return 2;      
    if(ch=='*'||ch=='/') return 3;      
    if(ch=='(') return 4;         
}      
           
int Scal(int x,int y,char ope)//两个数的运算      
{      
    if(ope=='+') return x+y;      
    if(ope=='-') return x-y;      
    if(ope=='*') return x*y;      
    if(ope=='/'&&y!=0) return x/y;      
}      
      
void Transform(int n)//将中缀表达式转化为后缀表达式      
{      
    int k=0;      
    for(int i=0;i<n;i++)      
    {      
        if(ch[i]>='0'&&ch[i]<='9')//当是数字的情况      
        {      
            if(i+1<n&&(ch[i+1]<'0'||ch[i+1]>'9')||i==n-1)//当是最后一个数字,或下一个元素是运算符      
            {      
                s2.push(ch[i]);      
                s2.push('#');      
            }      
            else      
                s2.push(ch[i]);      
        }      
        else      
        {      
            if(s1.empty()||ch[i]=='('||priority(ch[i])>priority(s1.top()))//当是运算符,有3种情况直接入栈      
                s1.push(ch[i]);                   
            else if(ch[i]==')')//当是右括号的情况      
            {      
                while(s1.top()!='(')      
                {      
                    s2.push(s1.top());        
                    s1.pop();      
                }      
                s1.pop();      
            }      
            else//当运算符优先级小于或等于S1栈顶运算符的优先级    
            {      
                while(!s1.empty()&&priority(ch[i])<=priority(s1.top())&&s1.top()!='(')//这里还要注意两个界限      
                {      
                    s2.push(s1.top());      
                    s1.pop();                 
                }      
                s1.push(ch[i]);       
            }         
        }      
      
    }      
    while(!s1.empty())//当表达式结束      
    {      
        s2.push(s1.top());      
        s1.pop();             
    }      
    while(!s2.empty()) //将栈内元素放回S2中      
    {      
        ch[k++]=s2.top();      
        s2.pop();         
    }      
    reverse(ch,ch+k);//将ch[]反向      
    ch[k]=0;      
}      
      
int Cal(int n)//后缀表达式计算      
{      
    int x,y,tmp=0,k=0;      
    for(int i=0;i<n;i++)      
    {      
        if(ch[i]=='#')//是#直接跳过      
            continue;      
        else if(ch[i]=='+'||ch[i]=='-'||ch[i]=='*'||ch[i]=='/')//是运算符弹出栈顶两元素计算后放回栈      
        {      
            x=s3.top();      
            s3.pop();      
            y=s3.top();      
            s3.pop();      
            x=Scal(y,x,ch[i]);      
            s3.push(x);      
        }      
        else//是数字字符      
        {      
            if(ch[i+1]=='#')//下一个元素是#      
            {      
                num[k++]=ch[i]-'0';      
                for(int i=0;i<k;i++)      
                    tmp+=(num[i]*(int)pow(10,k-i-1));      
                s3.push(tmp);      
                tmp=0;      
                k=0;                      
            }      
            else//下一个元素不是#      
            {      
                num[k++]=ch[i]-'0';       
            }         
        }      
    }      
    return s3.top();      
}      
      
int main()      
{      
    gets(ch);      
    Transform(strlen(ch));      
    cout<<Cal(strlen(ch))<<endl;      
    return 0;      
}      


二、自我提高版本(自行编写stack)

Stack.h
#ifndef _STACK_H_
#define _STACK_H_

template <typename T>
class Stack
{
public:
	Stack(int maxSize);
	~Stack();
	void Push(const T& n);
	void Pop();
	T& getTop() const;
	bool Empty() const;
private:
	T *s_;
	int top_;
	int maxSize_;
};

template <typename T>
Stack<T> :: Stack(int maxSize) : maxSize_(maxSize),top_(-1)
{
    s_ = new T[maxSize];
}

template <typename T>
Stack<T> :: ~Stack()
{
    delete[] s_;
}

template <typename T>
void Stack<T> :: Push(const T& n)
{
   if(top_ == maxSize_ -1)
   {
       throw(1);
   }
   top_++;
   s_[top_] = n;
}

template <typename T>
void Stack<T> :: Pop()
{
    if(Empty() == true)
	{
	    throw(1);
	}
	top_--;
}

template <typename T>
T& Stack<T> :: getTop() const
{
   if(Empty() == true)
   {
       throw(1);
   }
   return s_[top_];
}

template <typename T>
bool Stack<T> :: Empty() const
{
   return top_ + 1 == 0;
}

#endif
Cal.cpp
#include <iostream>      
#include <cstring>      
#include <algorithm>   
#include <cmath>      
#include "Stack.h"

using namespace std;      
      
Stack<char> s1(200);
Stack<char> s2(200);      
Stack<int> s3(200);      

char ch[150]={0}; 
int num[11];
            
int priority(char ch)    
{      
    if(ch==')')
	{
		return 1;   
	}
    if(ch=='+'||ch=='-') 
	{
		return 2;
	}
    if(ch=='*'||ch=='/') 
	{
		return 3;    
	}
    if(ch=='(') 
	{
		return 4;   
	}
}      
           
int Scal(int x,int y,char ope) 
{      
    if(ope=='+') 
	{
		return x+y;
	}
    if(ope=='-') 
	{
		return x-y;   
	}
    if(ope=='*') 
	{
		return x*y; 
	}
    if(ope=='/'&&y!=0) 
	{
		return x/y; 
	}
}      
      
void Transform(int n)      
{      
    int k=0;      

    for(int i=0;i<n;i++)      
    {      
        if(ch[i]>='0'&&ch[i]<='9')
        {      
            if(i+1<n&&(ch[i+1]<'0'||ch[i+1]>'9')||i==n-1)   
            {      
                s2.Push(ch[i]);      
                s2.Push('#');      
            }      
            else      
                s2.Push(ch[i]);      
        }      
        else      
        {      
            if(s1.Empty()||ch[i]=='('||priority(ch[i])>priority(s1.getTop()))     
			{
                s1.Push(ch[i]);  
			}
            else if(ch[i]==')')
            {      
                while(s1.getTop()!='(')      
                {      
                    s2.Push(s1.getTop());        
                    s1.Pop();      
                }      
                s1.Pop();      
            }      
            else
            {      
                while(!s1.Empty()&&priority(ch[i])<=priority(s1.getTop())&&s1.getTop()!='(')     
                {      
                    s2.Push(s1.getTop());      
                    s1.Pop();                 
                }      
                s1.Push(ch[i]);       
            }         
        }      
      
    }      
    while(!s1.Empty())
    {      
        s2.Push(s1.getTop());      
        s1.Pop();             
    }      
    while(!s2.Empty()) 
    {      
        ch[k++]=s2.getTop();      
        s2.Pop();         
    }      
    reverse(ch,ch+k);
    ch[k]=0;      
}      
      
int Cal(int n)
{      
    int x;
	int y;
	int tmp=0;
	int k=0;      

    for(int i=0;i<n;i++)      
    {      
        if(ch[i]=='#')
		{
            continue; 
		}
        else if(ch[i]=='+'||ch[i]=='-'||ch[i]=='*'||ch[i]=='/')
        {      
            x=s3.getTop();      
            s3.Pop();      
            y=s3.getTop();      
            s3.Pop();      
            x=Scal(y,x,ch[i]);      
            s3.Push(x);      
        }      
		else      
        {      
            if(ch[i+1]=='#') 
            {      
                num[k++]=ch[i]-'0';      
                for(int i=0;i<k;i++)      
                    tmp+=(num[i]*(int)pow(10,k-i-1));      
                s3.Push(tmp);      
                tmp=0;      
                k=0;                      
            }      
            else
            {      
                num[k++]=ch[i]-'0';       
            }         
        }      
    }      
    return s3.getTop();      
}      
      
int main()      
{      
    cin >> ch;   

    Transform(strlen(ch));

    cout<<Cal(strlen(ch))<<endl;      

    return 0;      
}      




  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值