V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
XhstormR
V2EX  ›  Java

自己实现一个简单计算器碰到了一个问题,不知如何解决。

  •  
  •   XhstormR ·
    XhstormR · 2016-07-20 23:25:01 +08:00 · 3405 次点击
    这是一个创建于 3046 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我把输入都保存到一个 String 里面,空格为分隔符:

    String a = "1.5 + 5 * 8 - 1.6";
    

    然后转为 String[]:

    String[] b = a.split(" ");
    

    再通过奇偶判断数字与运算符,生成一个数字 double[]:

    double[] c = new double[(b.length + 1) / 2];
    for (int j = 0, i = 0; j < b.length; j++) {
        if (j % 2 == 1) {
            continue;
        }
        c[i] = Double.parseDouble(b[j]);
        i++;
    }
    for (double i : c) {
        System.out.print(i + " ");
    }
    输出: 1.5 5.0 8.0 1.6
    

    然后怎么解决运算符这个问题就想不出法了,怎么构造一个 数字 运算符 数字 运算符 数字 的式子啊?

    还是有更好的方法?

    12 条回复    2016-07-23 13:57:16 +08:00
    aheadlead
        1
    aheadlead  
       2016-07-20 23:30:03 +08:00
    不太明白楼主想说什么。

    大三的时候编译原理课程提到过表达式求值,推荐楼主看看编译原理的资料。
    SeanChense
        2
    SeanChense  
       2016-07-20 23:31:33 +08:00 via iPhone   ❤️ 1
    用栈实现的前、中、后缀表达式可以满足。
    MrGba2z
        3
    MrGba2z  
       2016-07-20 23:42:40 +08:00   ❤️ 1
    搜索下逆波兰表达式看看是否有帮助
    liuhaotian
        4
    liuhaotian  
       2016-07-20 23:57:23 +08:00 via iPhone   ❤️ 1
    逆波兰式 也就是后缀表达式 就可以直接求值
    比如 1+ 3 * 4 的逆波兰式是
    1 3 4 * +
    从左到右计算就可以得到结果
    XhstormR
        5
    XhstormR  
    OP
       2016-07-21 00:01:57 +08:00
    @liuhaotian 嗯,懂了,现在就是通过栈来实现它,还要现学栈。
    bkjzs
        6
    bkjzs  
       2016-07-21 01:52:36 +08:00 via Android
    嗯,可以使用内置 JS 引擎实现,简单粗暴。。
    quadpixels
        7
    quadpixels  
       2016-07-21 02:42:55 +08:00   ❤️ 1
    楼主问的“怎么构造一个 数字 运算符 数字 运算符 数字 的式子”的话,应该是语法树吧?
    那我就建立一个类叫做 Token , Token 里面含有一个 string ,是原字串内容; Token 有两个子类分别为表示运算符的 OpToken 和表示数字的 NumberToken ,运算符的 Token 里面存一个枚举表示是什么运算, NumberToken 里面存一个数表示这个数的值(不是字符串表示的字面值)。然后新建一个栈是 stack<Token> ,存放在解析过程中拿到的所有的 Token 。

    这个题目和 2013 年的时候在网上出现的一门叫 《 CPPGM 》的公开课的第三个作业( PA3 )(“ ctrlexpr ” )(=control expression )蛮相似的。在那个公开课里 PA3 继承了 PA2 ,而在 PA2 里所有的这些解析出来的元素也都是称作 Token 的,具体则叫作 PreprocessingToken 。
    fr000
        8
    fr000  
       2016-07-21 12:21:42 +08:00 via Android
    《自制编程语言》第二章就是干这个事情的,可以参考一下
    hyq
        9
    hyq  
       2016-07-21 14:36:04 +08:00   ❤️ 1
    talk is cheap, see my code
    用从上到下的方式撸了一个,楼主可以看看。

    https://gist.github.com/hyqhyq3/fb36e56f6d7863b9aeb48e1cd6c1ee50
    owt5008137
        10
    owt5008137  
       2016-07-21 15:40:41 +08:00 via Android
    https://www.owent.net/MiV4x

    你把它翻译成 java 吧
    zacard
        11
    zacard  
       2016-07-21 16:01:10 +08:00
    求这种表达式有个经典的算法:双栈算法。
    1.将操作数压入操作数栈
    2.将运算符压入运算符栈
    3.忽略左括号
    4.遇到右括号弹出运算符和所需的操作数
    5.将结果压入操作数栈
    XhstormR
        12
    XhstormR  
    OP
       2016-07-23 13:57:16 +08:00
    Finish !
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2680 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 12:15 · PVG 20:15 · LAX 04:15 · JFK 07:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.