用Java标记中缀字符串

时间:2014-01-28 14:39:23

标签: java regex tokenize shunting-yard

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

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

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

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

1 个答案:

答案 0 :(得分:5)

尝试使用正则表达式.split

(?<=[^\.a-zA-Z\d])|(?=[^\.a-zA-Z\d])

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

  • (?<=[^\.a-zA-Z\d])positive lookbehind。如果前面的字符串与(?<=...)中包含的子正则表达式匹配,则它匹配两个字符之间的位置。
    • [^\.a-zA-Z\d]negated character class。它匹配[^...]中未包含的单个字符
      • \.匹配字符.
      • a-z匹配az之间的任何小写字母。
      • A-Z是相同的,但是大写。
      • \d相当于[0-9],因此它匹配任何数字。
  • |the equivalent of an "or"。它使正则表达式与正则表达式的前一半或后一半匹配。
  • (?=[^\.a-zA-Z\d])与正则表达式的前半部分相同,只是它是positive lookahead。如果跟随字符串与(?=...)中包含的子正则表达式匹配,则匹配两个字符之间的位置。

您可以在java中实现此正则表达式:

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

结果:

["sin","(" 4,"+",3,")","-","8"]