Java初学者求助:如何判断StringTokenizer生成的Token是否为数字
解决StringTokenizer判断多位数数字的问题
嘿,我懂你现在的困扰——用StringTokenizer拆分中缀表达式后,没法准确识别多位数的数字,用equals()完全不管用对吧?毕竟数字可能是1位、2位甚至更多,不可能提前把所有数字都写进equals判断里。给你几个实用的解决方案,结合你的代码场景来给你讲:
方法1:正则表达式判断(最推荐)
正则可以轻松匹配任意位数的整数、负数甚至小数,直接用matches()方法就行,代码示例如下:
public String infixToPostfix() { Stack<String> s = new Stack<>(); String expression = jtfInfix.getText(); // 注意第三个参数设为true,这样会保留运算符和括号这些分隔符 StringTokenizer strToken = new StringTokenizer(expression, "+-*/() ", true); StringBuilder postfix = new StringBuilder(); while (strToken.hasMoreTokens()) { String token = strToken.nextToken().trim(); if (token.isEmpty()) continue; // 跳过拆分后产生的空字符串 // 用正则匹配数字:支持负数、整数、小数 if (token.matches("-?\\d+(\\.\\d+)?")) { postfix.append(token).append(" "); // 数字直接加入后缀表达式 } else { // 这里处理运算符、括号的栈逻辑,比如入栈、出栈判断优先级等 // 示例:如果是左括号直接入栈 if (token.equals("(")) { s.push(token); } else if (token.equals(")")) { // 弹出栈内元素直到遇到左括号 while (!s.isEmpty() && !s.peek().equals("(")) { postfix.append(s.pop()).append(" "); } s.pop(); // 弹出左括号,不加入后缀表达式 } else { // 处理运算符优先级,这里需要你自己实现优先级判断逻辑 while (!s.isEmpty() && getPriority(s.peek()) >= getPriority(token)) { postfix.append(s.pop()).append(" "); } s.push(token); } } } // 弹出栈内剩余的运算符 while (!s.isEmpty()) { postfix.append(s.pop()).append(" "); } return postfix.toString().trim(); } // 辅助方法:返回运算符优先级 private int getPriority(String op) { return switch (op) { case "+", "-" -> 1; case "*", "/" -> 2; default -> 0; // 括号优先级设为0 }; }
正则表达式-?\\d+(\\.\\d+)?的含义:
-?:匹配可选的负号(支持负数)\\d+:匹配1位或多位数字(\\.\\d+)?:可选的小数部分,匹配小数点加至少一位数字
方法2:用try-catch尝试转换数字
如果你的表达式里只有整数或小数,可以尝试把token转换成数字,成功就是数字,失败则是运算符/括号:
private boolean isNumber(String token) { try { Double.parseDouble(token); // 支持整数和小数 return true; } catch (NumberFormatException e) { return false; } }
然后在循环里调用这个方法:
if (isNumber(token)) { // 处理数字逻辑 } else { // 处理运算符/括号逻辑 }
方法3:自定义字符判断逻辑
如果不想用正则或try-catch,也可以逐个检查token的字符:
private boolean isNumber(String token) { if (token.isEmpty()) return false; int start = 0; // 处理负号,只能在第一个字符 if (token.charAt(0) == '-' && token.length() > 1) { start = 1; } // 检查剩余字符是否都是数字或小数点(注意小数点只能出现一次) boolean hasDot = false; for (int i = start; i < token.length(); i++) { char c = token.charAt(i); if (c == '.') { if (hasDot) return false; // 多个小数点,不是合法数字 hasDot = true; } else if (!Character.isDigit(c)) { return false; } } return true; }
关键提示
别忘了使用StringTokenizer时,第三个参数要设为true!这样才能保留+-*/()这些分隔符,不然你拆分后会丢失运算符,根本没法完成中缀转后缀的逻辑。
内容的提问来源于stack exchange,提问作者lio
相关产品推荐
相关产品推荐

