`
JAVA天地
  • 浏览: 673785 次
  • 性别: Icon_minigender_1
  • 来自: 太原
文章分类
社区版块
存档分类
最新评论

对一个可进行带括号、加减乘除运算类的分析

阅读更多

源程序来源于:http://bbs.tarena.com.cn/viewthread.php?tid=102826&extra=&page=1

这里主要对该程序的运行进行基本的分析,搞清楚其原理。因为我本人原来在参加面试的时候遇到过这样的问题,当时就没有答上来,有点后悔,所有这里补补。

这个程序主要采用的是将数进行压栈的方式,我们知道栈的方式是先进后出,一直遇到当前阶段优先级最高的才做运算,如这个表达式:"1+2*(3+4)",这里的数字栈和运算符分别变化如下:

栈数/符的推入就不例出来了,这里主要例当遇到最高级别的运算符的时候,如何进行运算的:

数字栈:1234

运算符栈:#+*(+

===========================

数字栈:127

运算符栈:#+*(

===========================

数字栈:127

运算符栈:#+*

===========================

数字栈:114

运算符栈:#+

===========================

数字栈:15

运算符栈:#

===========================

到这里根据条件就运算完了,就得到了我们想要的结果。源程序如下:

import java.util.Stack;
public class MyCal {
    // 运算符优先级比较函数
    static int co(char a, char b) {
        if (a == '+' || a == '-') {
            if (b == '+' || b == '-' || b == ')' || b == '#')
                return 1; // a>b
            return -1; // ab
        }
        if (a == '(' || a == '#') {
            if (a == '(' && b == ')')
                return 0; // a==b
            else if (a == '(' && b == '#')
                return 2; // can't compare
            else if (a == '#' && b == ')')
                return 2;
            else if (a == '#' && b == '#')
                return 0;
            else
                return -1;
        }
        if (a == ')') {
            if (b == '(')
                return 2;
            else
                return 1;
        }
        return 0;
    }

    // 判断表达式中数字的函数
    boolean isnum(char ch) {
        if ((ch >= '0' && ch <= '9') || ch == '.')
            return true;
        return false;
    }

    // 判断表达式中运算符的函数
    static boolean issign(char ch) {
        if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || 
            ch == ')' || ch == '#')
            return true;
        return false;
    }

    // 计算最简表达式值的函数
    // a和b是操作数,s是运算符
    static double cal(double a, char s, double b) {
        if (s == '+')
            return a + b; // a+b返回a+b的值
        if (s == '-')
            return b - a; // 由于操作数出栈顺序是后进先出,所以减法和除法要、返回值表达式中要交换参数的顺序
        if (s == '*')
            return a * b; // a*b返回a*b的值
        if (s == '/')
            return b / a; // 同减法
        return 0;
    }

    // 计算整个表达式值的函数
    static double calculate(String s) {
        s += "#";
        int i = 0; // 表达式循环条件
        char c; // 表达式中的一个字符
        Stack<double> num = new Stack<double>(); // 操作数栈
        Stack<character> op = new Stack<character>(); // 操作符栈
        op.push('#'); // 表达式开始的标志
        c = s.substring(i, i + 1).charAt(0); // 取出表达式中的一位
        while (c != '#' || 
               op.peek().toString().charAt(0) != '#') // 没有取到表达式开始或结束的标志'#',就循环计算表达式的值
        {
            if (!issign(c)) // 取到的字符是数字,那么就要取出整个数字
            {
                int start = i;
                int end = 0;
                while (!issign(s.substring(i, i + 1).charAt(0)))
                    // 只要s[i]是数字,就表示一个数还没完
                    end = i++; // 循环条件自加
                double m = 
                    Double.parseDouble(s.substring(start, end + 1)); // 取出从i位开始的数字
                num.push(m); // 数字入栈
                c = s.substring(i, i + 1).charAt(0); // 下一个字符
            } else // 取到的字符是运算符
            {
                switch (co(op.peek(), c)) // 与栈中的运算符比较优先级
                {
                case -1: // 栈中运算符优先级小于当前运算符
                    op.push(c); // 运算符入栈
                    i++;
                    c = s.substring(i, i + 1).charAt(0);
                    break;
                case 0: // 栈中运算符优先级等于当前运算符
                    op.pop(); // 运算符出栈
                    i++;
                    c = s.substring(i, i + 1).charAt(0);
                    break;
                case 1: // 栈中运算符优先级大于当前运算符
                    // 两次取出操作数栈中的数
                    double a = num.pop();
                    double b = num.pop();
                    // 取出运算符栈中的运算符
                    char ss = op.pop();
                    // 计算结果保存在数字栈中
                    num.push(cal(a, ss, b));
                    break;
                }
            }
        }
        return num.peek(); // 表达式计算完毕,返回数字栈中保存的计算结果
    }
    //测试

    public static void main(String[] args) {
        System.out.println(MyCal.calculate("1+2*(3+4)"));
        //System.out.println(MyCal.calculate("1+2*3+5+Math.max(1,3)"));
    }
}<pre></pre></character></character></double></double>
分享到:
评论

相关推荐

    一个可以实现括号、加减乘除优先级运算的计算器

    在编程领域,构建一个可以处理括号和加减乘除优先级运算的计算器是一项常见的练习。这个"一个可以实现括号、加减乘除优先级运算的计算器"项目旨在为安卓新手提供一个学习平台,让他们了解如何处理复杂的数学表达式。...

    Java编写的计算器图形界面实现加减乘除带括号运算

    Java编写的计算器图形界面实现加减乘除带括号运算 版本1.0 1、图形化界面 2、计算器显示部分分为两个区域:第一行显示输入将要计算的数值及符号,第二行显示结果,第一行字体要小,第二行字体要大,且加粗。 ...

    同个数加减乘除得到某数(不使用括号)

    标题“同个数加减乘除得到某数(不使用括号)”涉及到的是一个数学问题,探讨如何通过单一数字的不同算术运算(加法、减法、乘法、除法)来构造出目标数,而过程中不使用括号来改变运算顺序。这种问题在编程领域中有时...

    输入字符串实现加减乘除四则运算(java)

    将近250行的算法 实现了通过字符串进行加减乘除四则运算 纯通过处理字符串和数组实现 希望能帮助大家: 例如:String input &quot;33+26 77+70&quot;; String result &quot;&quot;; try { result Account...

    计算器运算逻辑实现(带括号,求余,乘方,加减乘除),不使用eval函数-前端JavaScript 源码实现-括号匹配与初等运算

    在前端开发中,实现一个计算器功能是一项常见的任务,特别是当这个计算器需要处理复杂的运算,如括号、求余、乘方以及加减乘除时。本文将深入探讨如何使用JavaScript来实现这样的计算器逻辑,不依赖于`eval`函数,...

    新人教七年级数学有理数的加减乘除乘方混合运算PPT课件.pptx

    新人教七年级数学有理数的加减乘除乘方混合运算PPT课件 以下是关于新人教七年级数学有理数的加减乘除乘方混合运算PPT课件的详细知识点: 一、有理数的混合运算顺序 在进行有理数的混合运算时,需要遵守一定的顺序...

    超长大整数四则运算BigInt加减乘除

    大整数四则运算 BigInt 加减乘除 括号 优先级,Python支持无限精度的运行,Java有BigInteger类,但是对C和C++就只能自己实现,这是一个带加减乘除运算的实现。

    JAVA计算器可实现整数加减乘除运算

    在这个名为"JAVA计算器可实现整数加减乘除运算"的项目中,我们关注的是一个具有用户友好界面的计算器,能够执行基本的数学运算,包括加法、减法、乘法和除法。 首先,我们需要了解Java中的GUI库,如Java Swing或...

    表达式求值包含括号加减乘除的运算

    表达式求值包含括号加减乘除的运算计算出表达式结果

    我做的多则运算支持括号加减乘除

    标题中的“我做的多则运算支持括号加减乘除”指的是一个计算器程序,它能够处理包含括号的数学表达式,并执行基本的四则运算(加法、减法、乘法和除法)。这个计算器是由Java编程语言实现的,显示了开发者在编程和...

    c#计算器混合运算(加减乘除括号)

    在C#编程中,创建一个支持混合运算的计算器是一项常见的任务,这涉及到处理加法、减法、乘法、除法以及括号内的运算。在这个项目中,开发者使用了栈数据结构来解决这个问题。栈是一种后进先出(LIFO)的数据结构,...

    四则运算源代码 包括了带大中小括号的加减乘除运算

    10分不多用来刷分的, 随便你怎么评价, 评价后系统会还你11分的

    Qt简易计算器(带括号加减乘除)

    压缩包内为完整项目文件,可直接使用 Qt version:5.14 IDE:Qt内置编译器 C++ 表达式求值方法:中缀表达式转后缀表达式,后缀表达式求值。 资源详细情况见博文:...

    计算器 实现加减乘除混合运算

    在Android开发中,创建一个能够实现加减乘除混合运算的计算器是一项常见的任务。这个计算器不仅需要处理基本的数学运算,还要能优雅地处理复杂的表达式。以下将详细讲解实现这个功能所需的关键知识点。 首先,我们...

    整数的加减乘除运算

    本文将详细探讨如何在VC6.0环境下进行单位整数的加减乘除运算,并讨论实现这些运算的方法以及注意事项。 首先,让我们了解一下VC6.0。Visual C++ 6.0是由Microsoft开发的一款集成开发环境(IDE),主要用于编写C++...

    小学二年级加减乘除混合运算计算题.pdf

    在小学二年级数学教学中,加减乘除混合运算是一个非常重要的知识点,它可以帮助学生巩固加减乘除的基础运算能力,并逐步过渡到更高级的数学运算。下面,我们将对该资源进行详细的分析和解读。 一、计算混合运算 在...

    初中数学正负数的加减乘除运算练习题归纳.docx

    本资源汇集了100道初中数学正负数的加减乘除运算练习题,旨在帮助学生巩固对正负数运算的理解和掌握。这些练习题涵盖了加减乘除四则运算,涉及到整数、分数、负数、绝对值等概念。 在这些练习题中,我们可以看到...

    有理数加减乘除混合运算.pdf

    总体来说,本文件内容包含了许多有理数加减乘除运算的例子,但由于扫描技术原因导致其中一些内容难以辨识,无法完全确保其准确性和完整性。然而,依据清晰的部分,我们还是可以提取出有理数运算的基本规则以及进行...

    计算器(加减乘除基本运算-带括号)

    我们需要编写各种测试用例,覆盖不同的运算情况,包括但不限于简单加减乘除、带有括号的复杂表达式、错误的表达式等。测试用例的设计应涵盖边界条件,如最大数字限制、除零错误等,以确保计算器在遇到这些情况时能给...

Global site tag (gtag.js) - Google Analytics