7-1 表达式转换(c++数据结构实验)

7-1 表达式转换

分数 35

全屏浏览题目

切换布局

作者 DS课程组

单位 浙江大学

算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。

输入格式:

输入在一行中给出不含空格的中缀表达式,可包含+-*/以及左右括号(),表达式不超过20个字符。

输出格式:

在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。

输入样例:

2+3*(7-4)+8/4

输出样例:

2 3 7 4 - * + 8 4 / +

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

代码如下:

#include<iostream>
using namespace std;
#define Status int 
#define ERROR 0
#define OK 1

template<class T>
struct Node {
    T data;
    Node<T>* next;
};

template<class T>
class LinkedStack {
private:
    Node<T>* top;
public:
    LinkedStack();
    ~LinkedStack();
    Status Gettop(T& e);
    Status Push(T e);
    Status Pop(T& e);
    Status IsEmpty();
    int Length();


};

template<class T>
LinkedStack<T>::LinkedStack() {

        top = new Node<T>;
        top->next = NULL;
}

template<class T>
LinkedStack<T>::~LinkedStack() {
    Node<T>* p;
    while (top != NULL) {
        p = top;
        top = top->next;
        delete p;
    }
}

template<class T>
Status LinkedStack<T>::Push(T e) {
    Node<T>* p = new Node<T>;
    if (!p) return ERROR;
    p->data = e;
    p->next = top->next;
    top->next= p;
    return OK;
}

template<class T>
Status LinkedStack<T>::Pop(T& e) {
    Node<T>* p;
    if (top->next == NULL) return ERROR;
    else {
        p = top->next;
        e = p->data;
        top->next = p->next;
        delete p;
        return OK;
    }
}

template<class T>
int LinkedStack<T>::Length() {
    Node<T>* p = top->next;
    int i = 0;
    while (p != NULL) {
        i++;
        p = p->next;
    }
    return i;
}

template<class T>
Status LinkedStack<T>::IsEmpty(){
    if(top->next==NULL) return OK;
    else return ERROR;
}

template<class T>
Status LinkedStack<T>:: Gettop(T& e){
    if(top->next==NULL) return ERROR;
    Node<T>* p=top->next;
    e=p->data;
    return OK;
}

/*判断是否为操作数*/
int Isnumber(char c){
    return (c>='0'&&c<='9');
}

/*判断是否为操作符*/
int Isoptr(char c){
    return (c=='+'||c=='-'||c=='*'||c=='/');

/*比较操作符的优先级*/
char compare2(char ptr1,char ptr2){
    if(ptr2=='#') return '>';
    else if(ptr2=='(') return '>';
    else if((ptr1=='*'||ptr1=='/')&&(ptr2=='+'||ptr2=='-'))  return '>';
    else if((ptr2=='*'||ptr2=='/')&&(ptr1=='+'||ptr1=='-'))  return '<';
    else return '=';
}

/*转换*/
char *change(char* str){
    LinkedStack<char> OPTR;
    char* result=new char[50];
    char* res=result;
    char* prior=NULL;
    char e;
    char ch;
    OPTR.Push('#');
    while(*str!='\0'){
        /*如果是操作数,要注意位数和小数点*/ 
        if(Isnumber(*str)){
            if(res!=result) *(res++)=' ';//如果不是第一个,则在该项前加空格 
            do{
                prior=str;
                *(res++)= *str;
                ++str;
            }while(Isnumber(*str)||*str=='.');
        }
        //(进栈 
        else if(*str=='('){
            OPTR.Push(*str);
            prior=str;
            str++;
            
        }
        //依次出栈 
        else if(*str==')'){
            do{
              OPTR.Pop(e);
              if(e=='(')  break;
              else{
                  if(res!=result) *(res++)=' ';
                  *(res++)=e;
              }    
            }while(1);
            prior=str;
            str++;
        }
        //如果是操作符,分为操作数的符号和运算符两种; 
        else if(Isoptr(*str)){
            //情况1 
            if(prior==NULL||*prior=='('){
                if(res!=result) *(res++)=' ';
                do{
                prior=str;
                if(*str!='+'){//特别注意+号要舍去 
                
                *(res++)= *str;
                }
                ++str;
                }while(Isnumber(*str)||*str=='.');
            }
            //情况2 
            else{
            
                do{
                OPTR.Gettop(ch);
                if(ch=='#') break;
                if(compare2(*str,ch)=='>'){
                    
                    break;
                }
                else if(compare2(*str,ch)=='<'||compare2(*str,ch)=='='){
                    if(res!=result) *(res++)=' ';
                    OPTR.Pop(e);
                    (*res++)=e;
                }
                
                }while(1);
                OPTR.Push(*str);
                prior=str;
                str++;
            }
        }
    }
    //对栈内剩下元素操作; 
    OPTR.Gettop(ch);
    while(ch!='#'){
        if(res!=result) *(res++)=' ';
        OPTR.Pop(e);
        *(res++)=e;
        OPTR.Gettop(ch);
    }
    *res='\0';
    return result;
}

int main()
{
    char m;
    //char *str=new char;  该方法会越界,导致pta运行时错误; 
    char *str=new char[50];
    char* p=str;
    char* result;
    while((m=getchar())!='\n'){
        *p=m;
        p++;
    }
    *p='\0';
    result=change(str);
    cout<<result;
    delete []str;
    
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值