您的位置: 翼速应用 > 业内知识 > Java > 正文

关于Java中缀表达式的详细实现方法

本文是关于Java中缀表达式的详细实现方法解析,中缀表达式不容易被计算机解析,但仍被许多程序语言使用,因为它符合人们的普遍用法。下面一起来看一下,希望对大家有帮助。


关于Java中缀表达式的详细实现方法


关于Java中缀表达式的详细实现方法


1.概念


什么是中缀表达式,什么是后缀表达式?


从小学开始学习的四则运算,例如:3+(5*(2+3)+7) 类似这种表达式就是中缀表达式。中缀表达式人脑很容易理解,各个算符的优先级,人脑也很容易判断,先算括弧里的,再算*,再算+,-


但是这种表达式很不利于计算机计算,通过某种方式把前缀表达式转换为后缀表达式方便计算机进行计算,如3+(5*(2+3)+7)的后缀表达式就是3,5,2,3,+,*,7,+, +。这个表达式计算机很容易计算,为什么容易计算,通过算法流程2,就会一个深入的理解。


2.算法流程


如何把中缀表达式转换成后缀表达式?比如说3+(5*(2+3)+7)的转成后缀表达式的流程如何?


操作符优先级:


●  +,- 小于*,/


●  + 等于 -


●  * 等于 /


左括号和右括号作为特殊操作符特殊处理。(碰到’(’不用判断优先级直接入操作符栈,碰到’)’,也不用判断优先级,直接出操作符栈)


大致算法掌握以下几个流程:


准备两个栈,一个是数字栈A,一个是操作符栈(+,-,*,/(,))B等


1.0 对于数字栈A,遇到数字直接入栈A。


2.0 对于操作符栈B,分几种情况


2.1 碰到 ‘(‘操作符直接入栈


2.2 碰到 ‘)’操作符,不停的把操作符栈B出栈,直到遇到’)’。(把’(’到’)’之间的弹出的操作符依次入栈A)


2.3 碰到’+,-,* /’比较当前元素(假设当前元素current)和B栈栈顶的操作符(假设栈顶元素是top)的优先级.


2.3.1 如果top >= current, B栈出栈且循环比较,直到top < current退出循环,且把 current入栈


2.3.2 如果top < current, 直接把current入B栈


3.0 扫描完整个字符串,如果B栈中还有操作符,依次出栈入A


按照上面算法演示3+(5*(2+3)+7)的流程:


演示3+(5*(2+3)+7)的流程


所以最终A的后缀表达式是3,5,2,3,+,*,7,+, +


计算机拿到这个会怎么计算呢?流程如下:


●  碰到数字直接入栈


●  碰到操作符,直接弹出两个栈顶元素,通过操作符计算,把结果压入栈


通过步骤1,2循环计算,最终栈里只会有一个元素,这个就是表达式的结果。


我们来演练一下:


计算机计算演练


通过上面可以得知,计算机很容易计算,从左扫描到右就能把结果得出。


3 代码实现


mid2post 求后缀表达式


calcPostExp 拿到后缀表达式求值


cmpPriority 优先级比较


//优先级
bool cmpPriority(char top, char cur)//比较当前字符与栈顶字符的优先级,若栈顶高,返回true
{
    if ((top == '+' || top == '-') && (cur == '+' || cur == '-'))
        return true;
    if ((top == '*' || top == '/') && (cur == '+' || cur == '-' || top == '*' || top == '/'))
        return true;
    if (cur == ')')
        return true;
    return false;
}


求后缀表达式求值


vector<string> mid2post(string &str)
{
 
    vector<string>vstr;
    stack<char>cstack;
    for (int i = 0;i<str.size();++i)//扫描字符串
    {
        string temp = "";
        if (str[i] >= '0' && str[i] <= '9')//若是数字
        {
            temp += str[i];
            while (i + 1<str.size() && str[i + 1] >= '0' && str[i + 1] <= '9')
            {
                temp += str[i + 1];//若是连续数字
                ++i;
            }
            vstr.push_back(temp);
        }
        else if (cstack.empty() || str[i] == '(')//若栈空或者字符为'('
            cstack.push(str[i]);
        else if (cmpPriority(cstack.top(), str[i]))//若栈顶元素优先级较高,栈顶元素出栈
        {
            if (str[i] == ')')//若当前字符是右括号,栈中元素出栈,入字符串数组中,直到遇到'('
            {
                while (!cstack.empty() && cstack.top() != '(')
                {
                    temp += cstack.top();
                    cstack.pop();
                    vstr.push_back(temp);
                    temp = "";
                }
                cstack.pop();
            }
            else//栈中优先级高的元素出栈,入字符串数组,直到优先级低于当前字符
            {
                while (!cstack.empty() && cmpPriority(cstack.top(), str[i]))
                {
                    temp += cstack.top();
                    cstack.pop();
                    vstr.push_back(temp);
                    temp = "";
                }
                cstack.push(str[i]);
            }
        }
        else//当前字符优先级高于栈顶元素,直接入栈
            cstack.push(str[i]);
    }
    while (!cstack.empty())//栈中还存在运算符时,出栈,存入字符串数组
    {
        string temp = "";
        temp += cstack.top();
        cstack.pop();
        vstr.push_back(temp);
    }
    return vstr;
}


对后缀表达式进行求值,主要是根据运算符取出两


int calcPostExp(vector<string> & vstr)//对后缀表达式进行求值,主要是根据运算符取出两个操作数进行运算
{
    int num, op1, op2;
    stack<int>opstack;
    for (int i = 0;i<vstr.size();++i)
    {
        string temp = vstr[i];
        if (temp[0] >= '0' && temp[0] <= '9')//如果当前字符串是数字,利用字符串流转化为int型
        {
            stringstream ss;
            ss << temp;
            ss >> num;
            opstack.push(num);
        }
        else if (vstr[i] == "+")//若是操作符,取出两个操作数,进行运算,并将结果存入
        {
            op2 = opstack.top();
            opstack.pop();
            op1 = opstack.top();
            opstack.pop();
            opstack.push(op1 + op2);
        }
        else if (vstr[i] == "-")
        {
            op2 = opstack.top();
            opstack.pop();
            op1 = opstack.top();
            opstack.pop();
            opstack.push(op1 - op2);
        }
        else if (vstr[i] == "*")
        {
            op2 = opstack.top();
            opstack.pop();
            op1 = opstack.top();
            opstack.pop();
            opstack.push(op1*op2);
        }
        else if (vstr[i] == "/")
        {
            op2 = opstack.top();
            opstack.pop();
            op1 = opstack.top();
            opstack.pop();
            opstack.push(op1 / op2);
        }
    }
    return opstack.top();//最终的栈顶元素就是求解的结果
}


以上就是关于Java中缀表达式的详细实现方法,翼速应用平台内有更多相关资讯,欢迎查阅!

我来说两句

0 条评论

推荐阅读

  • 响应式布局CSS媒体查询设备像素比介绍

    构建响应式网站布局最常见的是流体网格,灵活调整大小的站点布局技术,确保用户在使用的幕上获得完整的体验。响应式设计如何展示富媒体图像,可以通过以下几种方法。

    admin
  • 提升网站的性能快速加载的实用技巧

    网站速度很重要,快速加载的网站会带来更好的用户体验、更高的转化率、更多的参与度,而且在搜索引擎排名中也扮演重要角色,做SEO,网站硬件是起跑线,如果输在了起跑线,又怎么跟同行竞争。有许多方法可提升网站的性能,有一些技巧可以避免踩坑。

    admin
  • 织梦CMS TAG页找不到标签和实现彩色标签解决方法

    织梦cms是我们常见的网站程序系统的一款,在TAG标签中常常遇到的问题也很多。当我们点击 tags.php 页的某个标签的时候,有时会提示:“系统无此标签,可 能已经移除!” 但是我们检查程序后台,以及前台显示页面。这个标签确实存在,如果解决这个问题那?

    admin
  • HTML关于fieldset标签主要的作用

    在前端开发html页面中常用的标签很多,今天为大家带来的是关于HTML中fieldset标签主要的作用说明,根据技术分析HTML

    admin

精选专题