【经典】栈的应用:算术表达式求值

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+计算机其他笔记入口
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

记录一下自己新的突破,可能方法比较笨,但还是一行一行敲出来了。
运行如图所示:
在这里插入图片描述
总体算法思想:
①首先将中缀表达式转化为后缀表达式
②再计算后缀表达式

模块讲解:
①首先将中缀表达式转化为后缀表达式
计算后缀表达式算法思想:从数组中扫描,
当遇到一个数值时把它压入栈,遇到符号时,
弹出两个值,计算后,压入栈中


优先级口诀:
栈内的 “ *,/ ”符号 大于栈外的,站内的“+ - ” 符号大于栈外的
栈外的 “(” 大于栈内的

操作符 优先级表 # ( *,/ +,- )
isp(in Stack priority) 0 1 5 3 6
icp(in coming priority) 0 6 4 2 1
char* P_to_S(char *arr)//arr作为输入的表达式,比如(a+b)*2-2,注意‘('和')'均为英文输入
{
    stack<char> s;
    s.push('#');//优先级最低的
    char* p =new char(15);//为了在主函数中得到p指向一连串字符串的首地址,在不是函数main中,需要分配持久的内存
    int i=0,j=0;
    while(arr[i] != '\0')
    {
        if(arr[i]>='0'&&arr[i]<='9')
            p[j++] = arr[i];
        else
        {
            //当栈内有数据时,就需要比较栈内的运算符的优先级
            if(isp(s.top())>icp(arr[i]))//isp栈内优先,icp栈外优先数
            {
                p[j++] = s.top();
                s.pop();
            }
            else if(isp(s.top())==icp(arr[i]))
                s.pop();
            else
                s.push(arr[i]);
        }
        i++;
    }
    while(s.top() != '#')
    {
        if(s.top() == '(')
        {
            s.pop();
            continue;
        }
        p[j++]=s.top();
        s.pop();
    }
    p[j]='\0';
    return p;
}

②再计算后缀表达式
计算后缀表达式算法思想:从数组中扫描,
当遇到一个数值时把它压入栈,遇到符号时,
弹出两个值,计算后,压入栈中

int cal(char* arr)//计算后缀表达式
{
    char* p  = arr;
    int i =0;
    int num1=0,num2=0;
    while(p[i] != '\0')
    {
        if(p[i]<='9'&&p[i]>='0')
        {
            st.push(p[i]-'0');
        }
        else
        {
            num2 = st.top();
            st.pop();
            num1 = st.top();
            st.pop();
            switch(p[i])
            {
                case '+':st.push(num1+num2);break;
                case '-':st.push(num1-num2);break;
                case '*':st.push(num1*num2);break;
                case '/':st.push(num1/num2);break;
            }
        }
        i++;
    }
    return st.top();
}

完整代码:

#include <iostream>
#include <stack>
using namespace std;
stack<int> st;
int cal(char* arr);//计算后缀表达式
int isp(char ch);//返回栈内运算符的优先级
int icp(char ch);//返回栈外运算符的优先级
char* P_to_S(char *arr);
int main()
{
    char *arr = new char(10);;
    cout<<"请输入一串表达式:如(a+b)/2+3"<<endl;
    cin>>arr;
    cout<<cal(P_to_S(arr));
    return 0;
}
char* P_to_S(char *arr)//将前缀表表达式转化为后缀表达式
{
    stack<char> s;
    s.push('#');
    char* p =new char(15);//为了返回p的地址需要持久化分配内存
    int i=0;
    int j=0;
    while(arr[i] != '\0')
    {
        if(arr[i]>='0'&&arr[i]<='9')
        {
            p[j] = arr[i];
            j++;
        }
        else
        {
            //当栈内有数据时,就需要比较栈内的运算符的优先级
            if(isp(s.top())>icp(arr[i]))//isp栈内优先,icp栈外优先数
            {
                p[j++] = s.top();
                s.pop();
            }
            else if(isp(s.top())==icp(arr[i]))
            {
                s.pop();
            }
            else
             {
                s.push(arr[i]);
             }
        }
        i++;
    }
    while(s.top() != '#')
    {
        if(s.top() == '(')
        {
            s.pop();
            continue;
        }
        p[j++]=s.top();
        s.pop();
    }
    p[j]='\0';
    return p;
}
int isp(char ch)//isp==in stack ,根据栈中的符号,返回优先级
{
    switch(ch)
    {
        case '#':return 0;
        case '(':return 1;
        case '+':return 3;
        case '-':return 3;
        case '*':return 5;
        case '/':return 5;
        case ')':return 6;
    }
}
int icp(char ch)//in coming==scp ,根据栈中的符号,返回优先级
{
    switch(ch)
    {
        case '#':return 0;
        case '(':return 6;
        case '+':return 2;
        case '-':return 2;
        case '*':return 4;
        case '/':return 4;
        case ')':return 1;
    }
}
int cal(char* arr)//计算后缀表达式
{
    char* p  = arr;
    int i =0;
    int num1=0,num2=0;
    while(p[i] != '\0')
    {
        if(p[i]<='9'&&p[i]>='0')
        {
            st.push(p[i]-'0');
        }
        else
        {
            num2 = st.top();
            st.pop();
            num1 = st.top();
            st.pop();
            switch(p[i])
            {
                case '+':st.push(num1+num2);break;
                case '-':st.push(num1-num2);break;
                case '*':st.push(num1*num2);break;
                case '/':st.push(num1/num2);break;
            }
        }
        i++;
    }
    return st.top();
}

猜你喜欢

转载自blog.csdn.net/qq_38173631/article/details/105300281
今日推荐