3

我正在研究一个适用于算法的迷你科学infix计算器postfix。我的输入是一个中缀字符串 .. 而我infix的 topostfix转换逻辑需要一个arrayof string。那么我怎样才能像这样拆分中缀字符串:

 100+(0.03*55)/45-(25+55)

到一个字符串数组,其中每个操作数和运算符都是一个数组元素。像这样

 "100" , "+" , "(" , "0.03" , "*" , "55" , ")" , "/" , "45" , "-"

等等...

请注意,字符串中没有空格,因此不能根据 regex 对其进行拆分" "

4

5 回答 5

2

您可以使用正则表达式来解析存储在字符串中的数学表达式。

expString.split("(?<=[-+*/\\(\\)])|(?=[-+*/\\(\\)])");

将为您解决问题。

说,

String str = "100+(0.03*55)/45-(25+55)";
String[] outs = str.split("(?<=[-+*/\\(\\)])|(?=[-+*/\\(\\)])");
for (String element : outs)
{
    System.out.println(element);
}

会给你一个输出,

100
+
(
0.03
*
55
)
/
45
-
(
25
+
55
)

请检查我的实验@http ://rextester.com/QEMOYL38160

于 2016-01-27T16:12:13.717 回答
2

显然,每个字符都是一个单独的标记,除了可能带有点的连续数字。因此,一个简单的解决方案是遍历字符串,然后当您看到一个数字前面有另一个数字(或小数分隔符,一个点)时,您将字符添加到前一个标记,否则将其添加到新标记.

这里的代码:

public static List<String> getTokens(String inputString) {
    List<String> tokens = new ArrayList<String>();
    // Add the first character to a new token. We make the assumption
    // that the string is not empty.
    tokens.add(Character.toString(inputString.charAt(0)));

    // Now iterate over the rest of the characters from the input string.
    for (int i = 1; i < inputString.length(); i++) {
        char ch = inputString.charAt(i); // Store the current character.
        char lch = inputString.charAt(i - 1); // Store the last character.

        // We're checking if the last character is either a digit or the
        // dot, AND if the current character is either a digit or a dot.
        if ((Character.isDigit(ch) || ch == '.') && (Character.isDigit(lch) || lch == '.')) {
            // If so, add the current character to the last token.
            int lastIndex = (tokens.size() - 1);
            tokens.set(lastIndex, tokens.get(lastIndex) + ch);
        }
        else {
            // Otherwise, add the current character to a new token.
            tokens.add(Character.toString(ch));
        }
    }
    return tokens;
}

请注意,此方法比大多数正则表达式方法更快

于 2016-01-27T16:12:35.367 回答
1

您需要使用前瞻并使用拆分向后查看。

这行得通。当然,如果您想包含更多元素,请改进正则表达式。

public static void main(String[] args) {
    String input = "100+(0.03*55)/45-(25+55)";
    String test[] = input.split("((?<=[\\+\\-\\*\\/\\(\\)\\{\\}\\[\\]])|(?=[\\+\\-\\*\\/\\(\\)\\{\\}\\[\\]]))");
    System.out.println(Arrays.toString(test));
}

更新 :

((?<=[a-z]]), 表示它将根据任何字符进行拆分,并将该字符包含在拆分后的数组中以及元素之后。

(?=[a-z]), 表示它将根据任何字符进行拆分,并将该字符包含在每个元素之前的拆分数组中。

|, 是两个正则表达式之间的 or 运算符。

[\\+\\-\\*\\/\\(\\)\\{\\}\\[\\]]), 是匹配可能组合的正则表达式

于 2016-01-27T16:16:29.743 回答
1

这是我将使用的算法:

从一个空字符串数组和一个空字符串缓冲区开始

  • 从字符 0 走到字符 n
  • 对于当前字符确定类型(数字/句点,打开括号,关闭括号,数学运算符)
  • 如果当前字符类型与最后一个字符类型相同
  • 将当前字符添加到缓冲区
  • 如果不相同,则将缓冲区放入字符串数组,并启动一个新缓冲区
于 2016-01-27T16:15:12.787 回答
0

请查看其他问题的答案。

这应该可以解决问题:

Pattern p = Pattern.compile("(?:(\\d+)|([+-*/\\(\\)]))");
Matcher m = p.matcher("100+(0.03*55)/45-(25+55)");
List<String> tokens = new LinkedList<String>();
while(m.find())
{
  String token = m.group( 0 ); //group 0 is always the entire match   
  tokens.add(token);
}
于 2016-01-27T16:10:43.907 回答