我编写了一段代码,用来接受用户的表达式:
( - (/ 3 4)0.5)
删除所有这样的空格:
( - (/ 34)0.5)
并将其保存到字符串数组中,然后将它们推送到堆栈
代码如下:
Scanner sc = new Scanner(System.in);
s = sc.nextLine();
sc.close();
s = s.replaceAll("\\s+","");
String [] x = s.trim().split("");
exprStack = new Stack<String>();
for (int i=0;i<x.length;i++){
exprStack.push(x[i]);//prints what goes to stack
System.out.println(x[i]);
}
然而,当我打印推送到堆叠的数组的元素时,分成两位数的分割,如 0.5 输出是:
(
-
(
/
3
4
)
0
.
5
)
答案 0 :(得分:1)
我认为你的目的是阅读元素并添加到堆栈中。如果您使用字符串,则会导致您当前遇到的问题。更好的方法是逐个读取每个元素并添加到堆栈。然后它不会拆分十进制数。另一种方法是指定每个元素空间分隔并通过 Scanner next()方法读取它们。
答案 1 :(得分:1)
实现此目的的最简单方法是使用positive lookaheads and lookbehinds在数字之间查找有效的运算符和空格。
拥有这些令牌后,只需过滤掉任何遗留空间。
/[ ]/ //
/(?<=[-+*/\(\) ])/ // Positive Lookbehind
/(?=[-+*/\(\) ])/ // Positive Lookahead
import java.util.Arrays;
public class Tokenizer {
public static String[] tokenize(String expression) {
String[] tokens = expression.split("(?<=[-+*/\\(\\) ])|(?=[-+*/\\(\\) ])");
String[] result = new String[tokens.length];
int i = 0;
for (String token : tokens) {
if (!token.equals(" ")) {
result[i++] = token;
}
}
return Arrays.copyOf(result, i);
}
public static void main(String[] args) {
String[] tokens = tokenize("(- ( / 8 14) 0.5)");
for (int i = 0; i < tokens.length; i++) {
System.out.printf("%2d. %s%n", i, tokens[i]);
}
}
}
0. (
1. -
2. (
3. /
4. 8
5. 14
6. )
7. 0.5
8. )
最好的方法是使用StringTokenizer
来解析字符串。你可以在这里找到一个例子:
我编写了一个简单的解析器来智能地找出什么是空格,数字或操作数。如果您想采取额外步骤,请查看ANTLR或其他语法/语言解析器。
此方法与上面的代码几乎相同,只是没有消除空格的后处理。他们只是被扫描仪吞噬了。
import java.util.*;
public class MathExpressionParser {
public static void main(String[] args) {
String[] tokens = parseExpression("(- ( / 8 14) 0.5)");
for (int i = 0; i < tokens.length; i++) {
System.out.printf("%2d. %s%n", i, tokens[i]);
}
}
public static String[] parseExpression(String expression) {
List<String> result = new ArrayList<String>();
Scanner scanner = new Scanner(expression);
scanner.useDelimiter("[ ]+(?<=[-+*/\\(\\) ])|(?=[-+*/\\(\\) ])");
while (scanner.hasNext()) {
result.add(scanner.next());
}
scanner.close();
return result.toArray(new String[result.size()]);
}
}
这是最好的方式。正则表达式可能变得非常大且难以管理,也会破坏性能。如果您正是您的标准,请继续并自行解析。它会加快性能,您可以在适当的时候轻松添加新条件。
import java.util.*;
public class MathExpressionParser {
public static void main(String[] args) {
String[] tokens = parseExpression("(- ( / 8 14) 0.5)");
for (int i = 0; i < tokens.length; i++) {
System.out.printf("%2d. %s%n", i, tokens[i]);
}
}
public static String[] parseExpression(String expression) {
List<String> result = new ArrayList<String>();
StringBuffer buffer = new StringBuffer();
for (char ch : expression.toCharArray()) {
if (Character.isWhitespace(ch)) {
bufferToItem(buffer, result);
} else {
if (Character.isDigit(ch) || ch == '.') {
buffer.append(ch);
} else {
bufferToItem(buffer, result);
result.add(Character.toString(ch));
}
}
}
return result.toArray(new String[result.size()]);
}
public static void bufferToItem(StringBuffer buffer, List<String> list) {
addItemIf(list, buffer);
clearBuffer(buffer);
}
public static void addItemIf(List<String> list, StringBuffer buffer) {
if (buffer.length() > 0) list.add(buffer.toString());
}
public static void clearBuffer(StringBuffer buffer) {
buffer.delete(0, buffer.length());
}
}