我正在尝试编写一个字符串评估函数,即。
evaluate("4 + 1") ; // returns 5
evaluate("4 + 1 + 3") ; // returns 8
evaluate("4 + 1 * 3") ; // returns 7 (not 15)
The operators are + - / and *
我的初期是使用正则表达式来收集运算符和数字,因为这些可以匹配。并且在找到该信息之后,以某种方式找出了优先考虑/*
ove -+
运营商的方法。
以下是我的开始:
static String regex = "([\\+\\*-/])+";
static String digitRegex = "(\\d)+";
public static void main(String[] args) {
System.out.println(getOperators("4 + 1 * 3"));
}
public static List<String> getOperators(String input) {
Pattern p = Pattern.compile(regex);
Matcher matcher = p.matcher(input);
List<String> operatorList = new ArrayList<String>();
int count = 0;
while (matcher.find()){
if (matcher.group(count) != null && matcher.group(count).trim().length() > 0) {
operatorList.add(matcher.group(count));
count++;
}
}
return operatorList;
}
现在我可以编写另一种方法来使用相同的逻辑提取数字。
public static List<Integer> getDigits(String input) {
Pattern p = Pattern.compile(digitRegex);
Matcher matcher = p.matcher(input);
List<Integer> digitList = new ArrayList<Integer>();
int count = 0;
while (matcher.find()) {
if (matcher.group(count) != null && matcher.group(count).trim().length() > 0) {
digitList.add(Integer.valueOf(matcher.group(count)));
count++;
}
}
return digitList;
}
现在是我被卡住的部分。 #1以上方法在第三个例子中失败:
evaluate("4 + 1 * 3") ; // returns 7 (not 15)
而这个#2即使我尝试前面的例子,我也无法弄清楚如何按正确的顺序排列它们。
我是否在正确的轨道上,是否有人有一些有用的建议请分享?
答案 0 :(得分:2)
我在这里写了一些东西......让我们说快速&amp;脏是轻描淡写......
无论如何,你不应该“按原样”使用它。它需要“修复” - 数字/算术运算的读取应该使用StringTokenizer来完成 - 但我会把技术性留给你;)
public class NewClass {
public static int evaluate(String str){
if("".equals(str)){
return 0;
}
else if(str.length() == 1){
return Integer.valueOf(str);
}
else{
String _a = String.valueOf(str.charAt(0));
String _b = String.valueOf(str.charAt(1));
if("+".equals(_b) || "-".equals(_b) ){
if("+".equals(_b)){
return Integer.valueOf(_a) + evaluate(str.substring(2));
}
else{// "-"
return Integer.valueOf(_a) - evaluate(str.substring(2));
}
}
else{// "*" or "/"
boolean isMulti = ("*".equals(_b));
String _c = String.valueOf(str.charAt(2));
Integer tmp = 0;
if(isMulti){
tmp = Integer.valueOf(_a) * Integer.valueOf(_c);
}
else{
tmp = Integer.valueOf(_a) / Integer.valueOf(_c);
}
String new_str = String.valueOf(tmp) + str.substring(3);
return evaluate(new_str);
}
}
}
public static void main(String[] args){
String e = "4+1*3";
int t = evaluate(e);
System.out.println(e + " = "+t);
}
}
答案 1 :(得分:1)
你想要一个operator precedence parser。这是一个非常常见的基于表的解析器,旨在完全按照您的意愿执行。基本上,您将正在扫描的操作员与堆栈顶部的操作员进行比较,然后选择减少堆栈(即,进行数学运算并将结果推回堆栈),或推动操作员。
作为额外的奖励,OPP很容易编写。您可以添加对括号等的支持,而无需额外的努力。
编辑 - 我刚读过那篇wiki文章。 太可怕了。
查找此类解析器的其他示例。
编辑2 -
This one shows a sample in c. Note the table.
请记住,你支持少数运营商,所以不要被吓倒。此外,一旦你实现了一个表,它就会一样。