我正在开发一个迷你科学计算器,使用中缀转后缀算法来运行。我的输入是中缀字符串..而我的中缀转后缀转换逻辑需要一个字符串数组。那么我该如何分割这样的中缀字符串:
100+(0.03*55)/45-(25+55)
将每个操作数和运算符作为数组元素组成一个字符串数组,格式如下:
"100" , "+" , "(" , "0.03" , "*" , "55" , ")" , "/" , "45" , "-"
请注意字符串中没有空格,因此无法基于正则表达式" "
进行拆分。
等等...
我正在开发一个迷你科学计算器,使用中缀转后缀算法来运行。我的输入是中缀字符串..而我的中缀转后缀转换逻辑需要一个字符串数组。那么我该如何分割这样的中缀字符串:
100+(0.03*55)/45-(25+55)
"100" , "+" , "(" , "0.03" , "*" , "55" , ")" , "/" , "45" , "-"
请注意字符串中没有空格,因此无法基于正则表达式" "
进行拆分。
等等...
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
)
显然,每个字符都是一个单独的标记,除了连续的数字可能有一个点。因此,一个简单的解决方案是迭代字符串,当你看到一个数字之前跟着另一个数字(或者小数分隔符,一个点)时,将字符添加到上一个标记中,否则添加到一个新标记中。
代码如下:
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;
}
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])
的意思是基于任何字符进行分割,并在每个元素之前将该字符包含在分割的数组中。
|
是两个正则表达式之间的或运算符。
[\\+\\-\\*\\/\\(\\)\\{\\}\\[\\]])
是匹配可能组合的正则表达式。
这是我会使用的算法:
从一个空的字符串数组和一个空的字符串缓冲区开始
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);
}
(?:(\\d+)|([+-*/\\(\\)])
,最外层的组没有被捕获,因此它从组0
开始。这可能会提高性能。 - Clashsoft