Java 计算不带分隔符的算术表达式
我想创建一个计算算术表达式的方法,例如Java 计算不带分隔符的算术表达式,java,algorithm,Java,Algorithm,我想创建一个计算算术表达式的方法,例如((2+100)*5)*7,在操作数和运算符之间不包含空格 如果有空格,我会使用split方法,将“作为分隔符 有人能帮我找到解决此类问题的算法吗?您可以使用Javascript计算整个表达式: ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("JavaScript"); String exp = "(
((2+100)*5)*7
,在操作数和运算符之间不包含空格
如果有空格,我会使用split方法,将“
作为分隔符
有人能帮我找到解决此类问题的算法吗?您可以使用Javascript计算整个表达式:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
String exp = "((2+100)*5)*7";
System.out.println(engine.eval(exp));
备选案文1:
您可以使用javascript引擎计算表达式
私有静态最终ScriptEngine引擎=新ScriptEngineManager().getEngineByName(“JavaScript”)
请注意,您必须将所有的^
转换为Math.pow
以获得电源
变式2
你可以使用
例:
输入:3+4
- 将3添加到输出队列(每当读取一个数字时,就会将其添加到输出队列)
- 将+(或其ID)推到运算符堆栈上
- 将4添加到输出队列
- 读取表达式后,将运算符从堆栈中弹出,并将它们添加到输出中
- 在这种情况下,只有一个“+”
private static final TreeMap操作符order=new TreeMap();
静止的
{
运算符order.put('(',0);
运算符order.put('),0);
运算符order.put(+',1);
运算符顺序.put('-',1);
运算符order.put('*',2);
运算符order.put('/',2);
运算符顺序.put('%',2);
运营者指令.放置('s',3);
运营者指令.put('l',3);
}
已执行私有void evalbuttonAction(java.awt.event.ActionEvent evt)
{
最终堆栈运算符ori=新堆栈();
最终堆栈值=新堆栈();
字符串expresie=exprTf.getText();
expresie=expresie.replaceAll(“sqrt”、“s”);
expresie=expresie.replaceAll(“ln”、“l”);
最终StringBuilder=新StringBuilder();
final char[]expresieChar=expresie.tocharray();
对于(int i=0;i来说,一种很好的方法是使用一些解析器生成器来创建输入文本的解析器。在java中,有几种很好的解析器。我建议使用ANTLR,因为您提供的示例在其一些基本教程中提供。关于这方面的更多详细信息,请参见另一个问题:
正如所指出的,被接受的答案有一个死链接。有一些可用的变体(如在编程语言中),您可以使用标记(例如特殊字符或大括号)。但我不会单独获取每个操作数。我需要我自己的方法(这是一种工作方式)。我只允许使用java方法。如果我有100+40,我怎么能得到每个操作数?我不能使用charAt:/如果你使用调车场算法,你有两个堆栈。一个用于操作数(数字),一个用于运算符(符号)。我知道..但是如果我想把堆栈推到一个操作数,我怎么能不使用charAt(可能是它的3位数字)得到它呢?我决定发布我的算法实现,因为它比使用带有正则表达式的Scanner.findInLine
读取运算符和操作数更容易理解XDP.S:第一个变体也是仅限java的。java集成了javascript引擎。
public static String eval(String expression){
if(expression == null){
return "NULL";
}
String js_parsable_expression = expression
.replaceAll("\\((\\-?\\d+)\\)\\^(\\-?\\d+)", "(Math.pow($1,$2))")
.replaceAll("(\\d+)\\^(\\-?\\d+)", "Math.pow($1,$2)");
try{
return engine.eval(js_parsable_expression).toString();
}catch(javax.script.ScriptException ex){
return "NULL";
}
}
private static final TreeMap<Character, Integer> operatorsOrder= new TreeMap<Character, Integer>();
static
{
operatorsOrder.put('(', 0);
operatorsOrder.put(')', 0);
operatorsOrder.put('+', 1);
operatorsOrder.put('-', 1);
operatorsOrder.put('*', 2);
operatorsOrder.put('/', 2);
operatorsOrder.put('%', 2);
operatorsOrder.put('s', 3);
operatorsOrder.put('l', 3);
}
private void evalButtonActionPerformed(java.awt.event.ActionEvent evt)
{
final Stack<Character> operatori = new Stack<Character>();
final Stack<Double> valori = new Stack<Double>();
String expresie = exprTf.getText();
expresie = expresie.replaceAll("sqrt", "s");
expresie = expresie.replaceAll("ln", "l");
final StringBuilder builder = new StringBuilder();
final char[] expresieChar = expresie.toCharArray();
for(int i = 0; i<expresieChar.length; i++)
{
char ch = expresieChar[i];
if (!operatorsOrder.containsKey(ch))
{
if(Character.isDigit(ch))
{
while (Character.isDigit(ch) || ch == '.')
{
builder.append(ch);
if(++i <expresieChar.length)
ch = expresieChar[i];
else
break;
}
--i;
valori.push(Double.parseDouble(builder.toString()));
builder.delete(0, builder.capacity());
}
continue;
}
while (true)
{
if (operatori.isEmpty() || ch == '(' || (operatorsOrder.get(ch) > operatorsOrder.get(operatori.peek())))
{
operatori.push(ch);
break;
}
final char op = operatori.pop();
if (op == '(')
{
if(ch == ')')
break;
}
else if(op == 's' || op == 'l')
{
final double val1 = valori.pop();
valori.push(eval(op, val1, 0));
}
else
{
final double val2 = valori.pop();
final double val1 = valori.pop();
valori.push(eval(op, val1, val2));
}
}
}
while (!operatori.isEmpty())
{
final char op = operatori.pop();
if(op == 's' || op == 'l')
{
final double val1 = valori.pop();
valori.push(eval(op, val1, 0));
}
else
{
final double val2 = valori.pop();
final double val1 = valori.pop();
valori.push(eval(op, val1, val2));
}
}
resultLabel.setText(String.valueOf(valori.pop()));
if(!operatori.isEmpty())
System.out.println("There are operators left.");
if(!valori.isEmpty())
System.out.println("There are operands left.");
}
}
public static double eval(char op, double val1, double val2)
{
switch (op)
{
case '+':
return val1 + val2;
case '-':
return val1 - val2;
case '/':
return val1 / val2;
case '*':
return val1 * val2;
case '%':
return val1 % val2;
case 's':
return Math.sqrt(val1);
case 'l':
return Math.log(val1);
default:
throw new RuntimeException("Operator is invalid.");
}
}