表达式的后缀表示

表达式的后缀表示

基本要求

  • 设计一转换程序,将输入的任一表达式转换成相应的后缀形式后输出。
  • 为简单起见,假定运算对象只含变量,且每个变量名以单字母表示;运算符仅含+、-、*、/和圆括号;表达式以分号“;”结尾。在转换过程中,要求作必要的语法检查,例如圆括号是否配对,单词是否合法等。
  • 分别编写转换程序的非递归与递归算法

    用栈实现非递归算法。首先给出栈的类定义,建议用一个头文件保存

#include<iostream>
#include<assert.h>
using namespace std;
const int stackIncreament = 20;//溢出时的扩容
template<class T> 
class SeqStack
{
public:
    T * elements;
    int top;
    int maxSize;
    void overflowProcess();
public:
    SeqStack(int sz =50);
    ~SeqStack(){ delete[]elements; }
    void Push( const T& x);
    bool Pop(T& x);
    bool Top(T& x);
    bool IsEmpty()const { return(top == -1) ? true : false; }
    bool IsFull()const { return (top == maxSize - 1) ? true : false; }
    int getSize()const { return top + 1; };
    void MakeEmpty() { top = -1; }
    friend ostream&operator<<(ostream& os, SeqStack<T>&s);
};
template <class T>
SeqStack<T>::SeqStack(int sz) :top(-1), maxSize(sz)
{
    //建立最大尺度为sz的空栈
    elements = new T[maxSize];//创建数组
    assert(elements != NULL);//断言:动态分配内存成功与否
}
template<class T>
void SeqStack<T>::overflowProcess()
{
    T* newArray = new T[maxSize + stackIncreament];
    if (newArray == NULL) { cerr << " new error!" << endl; exit(1); }
    for (int i = 0; i <= top; i++)newArray[i] = elements[i];
    maxSize = maxSize + stackIncreament;
    delete[]elements;
    elements = newArray;
}
template<class T>
void SeqStack<T>::Push(const T&x)
{
    if(IsFull()==true) overflowProcess();
    elements[++top] = x;
}
template<class T>
bool SeqStack<T>::Pop(T &x)
{
    if (IsEmpty() == true)return false;
    x = elements[top--];
    return true;
}
template <class T>
bool SeqStack<T>::Top(T&x)
{
    if (IsEmpty())return false;
    x = elements[top];
    return true;
}

语法检查函数,优先级预处理,都可以视为pre-operation

bool check_op(char a)
{
    if (a == '*' || a == '/' || a == '+' || a == '-' || a == '%')return true;
    return false;
}
map<char, int>isp; map<char, int>icp;
void Init()
{

    isp['#'] = 0; isp['('] = 1; isp['*'] = 5; isp['/'] = 5; isp['%'] = 5; isp['+'] = 3; isp[')'] = 6; isp['-'] = 3;
    icp['#'] = 0; icp['('] = 6; icp['*'] = 4; icp['/'] = 4; icp['%'] = 4; icp['+'] = 2; icp[')'] = 1; icp['-'] = 2;
}
bool pre_check(string expression)//语法检查
{
    int numl = 0, numr = 0;
    //最前面为操作符或者最后面为操作符,因为要求表达式以';'结尾,检查倒数第二个
    if (check_op(expression[0]) || check_op(expression[expression.size() - 2]))
    {
        cout << "表达式格式错误,please check!" << endl;
        return false;
    }

    for (int i = 0; i < expression.size()-1; i++)
    { 
        //连续的操作数
        if (isalpha(expression[i]) && isalpha(expression[i + 1])) {
            cout << "表达式格式错误,please check!" << endl;
            return false;
        }
        //连续的操作符
        if (check_op(expression[i]) && check_op(expression[i + 1])) {
            cout << "表达式格式错误,please check!" << endl;
            return false;
        }
        //左右括号是否匹配
        if (expression[i] == '(')numl++;
        if (expression[i] == ')')numr++;
    
    }
    if (numl != numr) {
        cout << "表达式格式错误,please check!" << endl;
        return false;
    }
        return true;
    
}

非递归算法,数据结构stack实现

void inffix_suffix(string expression)
{
    if (!pre_check(expression))return;
    //string sss = ";";
    Init();
    int i = 0;
    
    SeqStack<char>s;
    char ch = '#', ch1, op;
    s.Push(ch); ch = expression[i++];
    while (!s.IsEmpty() && ch != '#')
    {
        if (isalpha(ch)) { cout << ch; ch = expression[i++]; }//操作数直接输出
        else
        {
            s.Top(ch1);//栈顶元素ch1
            if (isp[ch1] < icp[ch]) { s.Push(ch); ch = expression[i++]; }//新输入的操作符优先级高,进栈
            else if (isp[ch1] > icp[ch]) { s.Pop(op); cout << op; }//优先级低,退栈
            else {
                s.Pop(op);//优先级相同,先左后右
                if (op == '(')ch = expression[i++];//此时说明,栈内的是'(',栈外的是')',ch = expression[i++]表示直接到')'的后一个
            }
        }
    }
    cout << endl;
}

递归写法

//此处没有再次进行语法检查,没有调用pre_check(expression))和Init();因为在main函数中,非递归先调用,以及调用前面两个函数
void inffix_suffix(string expression)
{
    if (!pre_check(expression))return;
    //string sss = ";";
    Init();
    int i = 0;
    
    SeqStack<char>s;
    char ch = '#', ch1, op;
    s.Push(ch); ch = expression[i++];
    while (!s.IsEmpty() && ch != '#')
    {
        if (isalpha(ch)) { cout << ch; ch = expression[i++]; }//操作数直接输出
        else
        {
            s.Top(ch1);//栈顶元素ch1
            if (isp[ch1] < icp[ch]) { s.Push(ch); ch = expression[i++]; }//新输入的操作符优先级高,进栈
            else if (isp[ch1] > icp[ch]) { s.Pop(op); cout << op; }//优先级低,退栈
            else {
                s.Pop(op);//优先级相同,先左后右
                if (op == '(')ch = expression[i++];//此时说明,栈内的是'(',栈外的是')',ch = expression[i++]表示直接到')'的后一个
            }
        }
    }
    cout << endl;
}

结束啦,欢迎大家指出错误之处

猜你喜欢

转载自www.cnblogs.com/gzr2018/p/9972914.html
今日推荐