public class Test {
public static void main(String[] args) {
SimpleCalculator s=new SimpleCalculator();
String methord="80*(1+0.5)"; //test
double d=s.evaluate(methord );
System.out.println(d);
}
}
import java.util.Scanner;
import java.util.Stack;
public class SimpleCalculator {
/**
* Evaluate an arithmetic expression, and return the result as a double.
*
* @param input
* the expression to evaluate.
* @return the evaluated result.
*/
public double evaluate(String input) {
initialize();
this.scanner = new Scanner(input);
this.scanner
.useDelimiter("\\s+|(?=[.0-9])(?<![.0-9])|(?![.0-9])(?<=[.0-9])|(?![.0-9])(?<![.0-9])");
Token currentToken = nextToken();
Token t = null;
while (null != currentToken) {
switch (currentToken.getKind()) {
case NUMBER:
// Simply push number tokens onto the evaluation stack.
this.eval.push(currentToken.getValue());
break;
case LPAREN:
// Simply push left parenthesis tokens onto the operator stack.
this.ops.push(currentToken);
break;
case RPAREN:
// Until a left parenthesis pops off the operator stack, keep
// poping operators and execute them.
// If the stack becomes empty without a matching left
// parenthesis,
// the expression must have syntax errors.
for (t = this.ops.pop(); TokenKind.LPAREN != t.getKind(); t = this.ops
.pop()) {
if (ops.empty())
throw new Error("Syntax Error: unmatched parenthesis");
doOperation(t);
}
break;
default:
// For binary arithmetic operators, keep poping operators whose
// binding power
// is less or equal to the current token's and execute them;
// after that push
// the current token onto the operator stack.
if (!ops.empty()) {
for (t = this.ops.pop(); currentToken.getKind()
.getBindingPower() < t.getKind().getBindingPower(); t = this.ops
.pop()) {
doOperation(t);
if (this.ops.empty()) {
t = null;
break;
}
}
}
if (null != t)
ops.push(t);
ops.push(currentToken);
break;
}
// reinitialize
currentToken = nextToken();
}
// execute remaining operators on stack
while (!ops.empty()) {
t = this.ops.pop();
doOperation(t);
}
// the result is on the top of evaluation stack,
// pop it off and return the result.
return this.eval.pop();
}
/*
* Initialize the evaluation and operator stacks.
*/
private void initialize() {
if (null == this.eval)
this.eval = new Stack<Double>();
if (null == this.ops)
this.ops = new Stack<Token>();
this.eval.clear();
this.ops.clear();
}
/*
* Return the next token from the input expression. The token returned will
* be associated with its numeric value, if and only if the token is a
* number.
*/
private Token nextToken() {
Token t = null;
if (this.scanner.hasNextDouble()) {
t = new Token(TokenKind.NUMBER, this.scanner.nextDouble());
} else if (this.scanner.hasNext()) {
String s = this.scanner.next("[-+*/()]");
if ("+".equals(s)) {
t = new Token(TokenKind.ADD);
} else if ("-".equals(s)) {
t = new Token(TokenKind.SUBTRACT);
} else if ("*".equals(s)) {
t = new Token(TokenKind.MULTIPLY);
} else if ("/".equals(s)) {
t = new Token(TokenKind.DIVIDE);
} else if ("(".equals(s)) {
t = new Token(TokenKind.LPAREN);
} else if (")".equals(s)) {
t = new Token(TokenKind.RPAREN);
}
}
return t;
}
/*
* Execute a binary arithmetic operation. Pop the top two values off the
* evaluation stack, do the operation, and then push the result back onto
* the evaluation stack.
*/
private void doOperation(Token t) {
double y = this.eval.pop();
double x = this.eval.pop();
double temp = t.getKind().doOperation(x, y);
this.eval.push(temp);
}
/*
* Tokenizer for the input expression.
*/
private Scanner scanner;
/*
* Evaluation stack.
*/
private Stack<Double> eval;
/*
* Operator stack, for converting infix expression to postfix expression.
*/
private Stack<Token> ops;
public static void main(String[] args) {
if (args.length < 1) {
System.err.println("Usage: java SimpleCalculator <expression>");
System.exit(1);
}
SimpleCalculator calc = new SimpleCalculator();
double result = calc.evaluate(args[0]);
System.out.println(result);
}
}
enum TokenKind {
// operators
ADD(1) {
public double doOperation(double x, double y) {
return x + y;
}
},
SUBTRACT(2) {
public double doOperation(double x, double y) {
return x - y;
}
},
MULTIPLY(3) {
public double doOperation(double x, double y) {
return x * y;
}
},
DIVIDE(4) {
public double doOperation(double x, double y) {
return x / y;
}
},
// punctuation
LPAREN(0), RPAREN(0),
// number
NUMBER(0);
TokenKind(int bindingPower) {
this.bindingPower = bindingPower;
}
public int getBindingPower() {
return this.bindingPower;
}
public double doOperation(double x, double y) {
return Double.NaN; // dummy, operation not supported
}
private int bindingPower;
}
class Token {
public Token(TokenKind kind) {
this(kind, Double.NaN);
}
public Token(TokenKind kind, double value) {
this.kind = kind;
this.value = value;
}
public TokenKind getKind() {
return this.kind;
}
public double getValue() {
return this.value;
}
private TokenKind kind;
private double value;
}
- Java:判断字符串是否为数字的五种方法
Java:判断字符串是否为数字的五种方法 //方法一:用JAVA自带的函数 public static boolean isNumeric(String str){ for (int i = str. ...
- Java中判断字符串是否为数字的五种方法
//方法一:用JAVA自带的函数 public static boolean isNumeric(String str){ for (int i = str.length();--i>=0;){ ...
- Java中判断字符串是否为数字的五种方法 (转)
推荐使用第二个方法,速度最快. 方法一:用JAVA自带的函数 public static boolean isNumeric(String str){ for (int i = str.length( ...
- 【工具类】Java中判断字符串是否为数字的五种方法
1 //方法一:用JAVA自带的函数 2 public static boolean isNumeric(String str){ 3 for (int i = str.length();--i> ...
- java中判断字符串是否为数字的三种方法
以下内容引自 http://www.blogjava.net/Javaphua/archive/2007/06/05/122131.html 1用JAVA自带的函数 public static ...
- java判断一个字符串是否是数字的三种方法
参考https://blog.csdn.net/ld_flex/article/details/7699161 1 用JAVA自带的函数 public static boolean isNumeric ...
- [转]java中判断字符串是否为数字的三种方法
1用JAVA自带的函数public static boolean isNumeric(String str){ for (int i = str.length();--i>=0;){ ...
- Java 判断字符串是否为空的四种方法、优缺点与注意事项
以下是Java 判断字符串是否为空的四种方法: 方法一: 最多人使用的一个方法, 直观, 方便, 但效率很低: if(s == null ||"".equals(s));方法二: ...
- String空格删除和java删除字符串最后一个字符的几种方法
1. String.trim()trim()是去掉首尾空格2.str.replace(" ", ""); 去掉所有空格,包括首尾.中间复制代码 代码如下:Str ...
随机推荐
- Pyqt 中__init__(self,parent==None) parent理解
参考: 在PyQt中,所有class都是从QObject派生而来,QWidget对象就可以有一个parent.这种parent-child关系主要用于两个方面: 没有parent的QWidget类被认 ...
- EXCEL中汉字转大写拼音
最近一直没有什么成系统的学习东西,也就没写什么随笔.昨天晚上,一哥们儿说给弄个输入汉字直接转拼音的程序,问了他几点需求,说你想做个啥的,最后,他说想做个EXCEL的,现在发现EXCEL确实是个好东西啊 ...
- IIS7报错
错误内容:”未能加载文件或程序集“IWMS_Admin”或它的某一个依赖项.试图加载格式不正确的程“ 解决方法:进入IIS“应用程序池”,然后在右边列表中,选中当前网站所使用的程序池,打开右侧的“高级 ...
- C# 使用 NPOI 库读写 Excel 文件
NPOI 是开源的 POI 项目的.NET版,可以用来读写Excel,Word,PPT文件.在处理Excel文件上,NPOI 可以同时兼容 xls 和 xlsx.官网提供了一份 Examples,给出 ...
- 最实用的APP界面设计知识,有温度的APP设计(转)
在逛简书的时候,无意之间看到了这样的一篇非常有意思的app设计博文.顾25学堂的摘录了其中的一些关于移动端APP界面设计的精华.分享给25学堂的app设计师们. 当然,下面的这些app设计知识点是来自 ...
- N种内核注入DLL的思路及实现
内核注入,技术古老但很实用.现在部分RK趋向无进程,玩的是SYS+DLL,有的无文件,全部存在于内存中.可能有部分人会说:"都进内核了.什么不能干?".是啊,要是内核中可以做包括R ...
- 记录linux /bin被误删除的解决过程
1.事因: 执行shell测试时,shell中rm -rf $path/* 变量$path为空,结果执行的命令是rm -rf / 事发时及时ctrl+c中断,导致只有/bin /boot目录删除 2. ...
- vim 标准环境的配置
最近刚刚从IDE转到了vim,很多习惯不一致,特地配置了一下vim环境.在网上找了大神的帖子,怕忘记了,特此纪念. 传送门 http://www.cnblogs.com/ma6174/arch ...
- mybatis中foreach的用法(转)
foreach一共有三种类型,分别为List,[](array),Map三种. foreach属性 属性 描述 item 循环体中的具体对象.支持属性的点路径访问,如item.age,item.inf ...
- js的一些小笔记,(不定期更新)
2个$的用法$本身并无特定意义,它表示什么意思要看是如何定义的,如果没有定义就便是两个$,可能是变量名的开始.一般是一个函数,用来代替document.getElementByIdfunction $ ...