我试图解决这样的等式:四加十除以(五十五加九)
以便我得到回复: 4.15625
我知道我可以这样解决String sentence = "4+10/(55+9)"
的等式:
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String infix = sentence;
try {
System.out.println(engine.eval(infix));
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
但无论如何只需要解决单词(nine..plus..divide ..)等式。 或者有没有办法将单词(nine..plus..divide ..)转换为像(9 ... + ... / ...)然后使用上面显示的函数来解决它?
谢谢!
答案 0 :(得分:1)
你可以选择像antlr这样的解析器库,如果你想要一个完整的,富有表现力的语言和正确的错误处理,这可能是更好的主意。
对于快速而肮脏的解决方案,您可以使用正则表达式和替换映射编写自己的解析器:
public class NaturalLanguageMath {
public static void main(String[] args) {
String sentence = "Four plus Ten divided by (fifty-five plus nine)";
System.out.println(toMath(sentence));
}
// Regular expression that will match our symbols
// special case for "divided by" since that's two words for one symbol
static final Pattern SYMBOL_PATTERN = Pattern.compile("(divided by|[a-z-]+)", Pattern.CASE_INSENSITIVE);
private static String toMath(String sentence) {
// Builder to build the translated string
StringBuilder builder = new StringBuilder();
// End of the last matched group
int lastEnd = 0;
// Go through all symbols in the string
Matcher matcher = SYMBOL_PATTERN.matcher(sentence);
while(matcher.find()) {
// The matched symbol
String symbol = matcher.group(0).toLowerCase();
// Get the replacement
String replacement = getReplacement(symbol);
// Append everything between the previous match and this match
builder.append(sentence.substring(lastEnd, matcher.start()));
// Append the replacement
builder.append(replacement);
// Update the end
lastEnd = matcher.end();
}
// Append the end of the string and return it
builder.append(sentence.substring(lastEnd));
return builder.toString();
}
// Map to hold replacement symbols
static final HashMap<String, String> REPLACEMENT_MAP = new HashMap<>();
static {
REPLACEMENT_MAP.put("four", "4");
REPLACEMENT_MAP.put("plus", "+");
REPLACEMENT_MAP.put("ten", "10");
REPLACEMENT_MAP.put("fifty", "50");
REPLACEMENT_MAP.put("five", "5");
REPLACEMENT_MAP.put("nine", "9");
REPLACEMENT_MAP.put("divided by", "/");
}
private static String getReplacement(String symbol) {
// Handle compounds such as fifty-five
if(symbol.contains("-")) {
// add each individual symbol together and return the result
// this is far from perfect since it will allow compounds such as
// fifty-five-nine which would become 64
int value = 0;
// Go through each individual symbol and translate it
String[] symbols = symbol.split("-");
for(String s : symbols) {
if(!REPLACEMENT_MAP.containsKey(s)) {
throw new IllegalArgumentException("Unknown symbol: " + s);
}
value += Integer.parseInt(getReplacement(s));
}
return String.valueOf(value);
// Straight translation
} else if (REPLACEMENT_MAP.containsKey(symbol)) {
return REPLACEMENT_MAP.get(symbol);
// Unknown symbol
} else {
throw new IllegalArgumentException("Unknown symbol: " + symbol);
}
}
}
输出:
4 + 10 /(55 + 9)