用Java标记中缀字符串

scr*_*rd3 4 java regex tokenize shunting-yard

我正在Java中实现Shunting Yard算法,作为我的AP计算机科学课程的一个副项目.我在Javascript中实现了一个简单的算法,只有基本的算术表达式(加法,减法,乘法,除法,取幂).要将它拆分成一个数组,我所做的就是找到每个运算符(+-*/^),以及数字和括号,然后在它们周围放置一个空格,然后我将它拆分成一个数组.例如,中缀字符串4+(3+2)将被制作成4 + ( 3 + 2 ),然后在空格上分割.

但是,我觉得这种方法非常慢,当你开始添加正弦,余弦,正切,绝对值等数学函数时,它实现起来越来越难以实现.

将字符串拆分sin(4+3)-8成数组的最佳方法是["sin","(" 4,"+",3,")","-",8]什么?

我可以使用正则表达式,但我并不是很了解它们,我正在努力学习它们,所以如果这对他们来说是最好的解决方案,请问回答者能解释它的作用吗?

The*_*Hat 6

试试.split正则表达式

(?<=[^\.a-zA-Z\d])|(?=[^\.a-zA-Z\d])
Run Code Online (Sandbox Code Playgroud)

它会在任何前面或后面跟着非字母数字字符或句点的地方拆分字符串.

  • (?<=[^\.a-zA-Z\d])是一个积极的看法.如果前面的字符串与其中包含的子正则表达式匹配,它匹配两个字符之间的位置(?<=...).
    • [^\.a-zA-Z\d]是一个否定的角色类.它匹配未包含的单个字符[^...].
      • \.匹配角色..
      • a-z匹配a和之间的任何小写字符z.
      • A-Z 是相同的,但对于大写.
      • \d相当于[0-9],所以它匹配任何数字.
  • |是一个"或"等效.它使正则表达式与正则表达式的前一半或后一半匹配.
  • (?=[^\.a-zA-Z\d])与正则表达式的前半部分相同,除了它是一个积极的前瞻.如果以下字符串与其中包含的子正则表达式匹配,则它匹配两个字符之间的位置(?=...).

您可以在java中实现此正则表达式,如下所示:

String str = "sin(4+3)-8";
String[] parts = str.split("(?<=[^\\.a-zA-Z\\d])|(?=[^\\.a-zA-Z\\d])");
Run Code Online (Sandbox Code Playgroud)

结果:

["sin","(" 4,"+",3,")","-","8"]
Run Code Online (Sandbox Code Playgroud)