5

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

但是,我觉得这种方法非常慢,并且随着您开始添加数学函数(例如正弦、余弦、正切、绝对值等),实现起来变得越来越困难和效率低下。

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

我可以为此使用正则表达式,但我不太了解它们,我正在努力学习它们,所以如果这对他们来说是最好的解决方案,那么回答者能否解释一下它的作用?

4

1 回答 1

7

尝试.split使用正则表达式

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

它将在非字母数字字符或句点之前或之后的任何位置拆分字符串。

  • (?<=[^\.a-zA-Z\d])是一个积极的回顾。它匹配两个字符之间的位置,如果前面的字符串匹配包含在(?<=...).
    • [^\.a-zA-Z\d]是一个否定字符类。它匹配不包含在中的单个字符[^...]
      • \.匹配字符.
      • a-z匹配a和之间的任何小写字符z
      • A-Z是一样的,但是是大写的。
      • \d等价于[0-9],因此它匹配任何数字。
  • |相当于"or"。它使正则表达式匹配正则表达式的前半部分或后半部分。
  • (?=[^\.a-zA-Z\d])与正则表达式的前半部分相同,只是它是一个积极的前瞻。它匹配两个字符之间的位置,如果以下字符串匹配包含在(?=...).

你可以像这样在java中实现这个正则表达式:

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

结果:

["sin","(" 4,"+",3,")","-","8"]
于 2014-01-28T14:48:54.267 回答