仿android计算器,实现了括号
发布时间:2020-12-14 23:20:47 所属栏目:Java 来源:网络整理
导读:今天PHP站长网 52php.cn把收集自互联网的代码分享给大家,仅供参考。 package com.fire.utils; import java.text.DecimalFormat;import java.text.NumberFormat;import java.util.ArrayList;import java.util.List;import
|
以下代码由PHP站长网 52php.cn收集自互联网 现在PHP站长网小编把它分享给大家,仅供参考
package com.fire.utils;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
/**
* 工具类
*
* @author FireAnt
*
*/
public class Tools {
public static int i = 0;
/**
* 计算一个合法的表达式的值
* @param exp
* @return
*/
public static String cal(String exp) {
// 特殊表达式的处理方式
if (exp.length() == 0) {
return "";
} else if (exp.length() == 1) {
if (exp.equals(".")) {
return "0";
} else {
return "";
}
} else if (exp.matches(".*÷0.*")) { // 0作为除数
return "∞";
} else if (exp.matches(".*[+-/×÷]")) {
exp = exp.substring(0,exp.length() - 1);
if (exp.equals(".")) {
return "0";
}
}
// 如果表达式中有括号则递归计算
if (exp.contains("(")) {
// 找出最后一个左括号
int left = exp.lastIndexOf("(");
// 找出第一个右括号
int right = exp.indexOf(")");
// 获取第一个子表达式
String subExp = exp.substring(left + 1,right);
// 计算子表达式的结果
String res = cal(subExp);
// 用计算出来的结果替换子表达式
exp = exp.substring(0,left) + res + exp.substring(right + 1);
// 递归计算新的表达式
exp = cal(exp);
}
// 格式化表达式
String newExp = formatExp(exp);
List<Character> opts = getOptions(newExp);
List<Double> nums = getNums(newExp);
// 先处理乘除
for (int i = 0; i < opts.size(); i++) {
char opt = opts.get(i);
if (opt == '÷' || opt == '×') {
opts.remove(i);
double d1 = nums.remove(i);
double d2 = nums.remove(i);
if (opt == '÷') {
d1 = d1 / d2;
} else {
d1 = d1 * d2;
}
nums.add(i,d1);
i--;
}
}
while (!opts.isEmpty()) {
char opt = opts.remove(0);
double d1 = nums.remove(0);
double d2 = nums.remove(0);
if (opt == '+') {
d1 = d1 + d2;
} else {
d1 = d1 - d2;
}
nums.add(0,d1);
}
return formatNum(nums.get(0));
}
/**
* 获得一个表达式中所有的运算符
* @param exp
* @return
*/
private static List<Character> getOptions(String exp) {
List<Character> opts = new ArrayList<Character>();
StringTokenizer st = new StringTokenizer(exp,"@.0123456789");
while (st.hasMoreTokens()) {
opts.add(st.nextToken().charAt(0));
}
return opts;
}
/**
* 获得一个表达式中所有的数字
* @param exp
* @return
*/
private static List<Double> getNums(String exp) {
List<Double> nums = new ArrayList<Double>();
StringTokenizer st = new StringTokenizer(exp,"+-×÷");
while (st.hasMoreTokens()) {
String num = st.nextToken();
if (num.contains("@")) {
num = "-" + num.substring(1);
}
nums.add(Double.parseDouble(num));
}
return nums;
}
/**
* 格式一个浮点数
* @param num
* @return
*/
public static String formatNum(double num) {
DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
df.applyLocalizedPattern("#0.##########");
if (num > 1000000000) {
df.applyPattern("#0.#######E0");
}
return df.format(num);
}
/**
* 格式化表达式
* 1.替换操作(找出负号,并将其替换成@符号)
* 2.避免非法表达式的出现
*/
private static String formatExp(String exp) {
// 如果表达式是以运算符结束的,则将最后一位运算符去除
if (exp.matches(".*[+-/×÷]")) {
exp = exp.substring(0,exp.length() - 1);
}
String res = exp;
if (exp.charAt(0) == '-') {
res = "@" + res.substring(1);
}
for (int i = 1; i < res.length(); i++) {
if (res.charAt(i) == '-' && (res.charAt(i - 1) == '÷' || res.charAt(i - 1) == '×')) {
res = res.substring(0,i) + "@" + res.substring(i + 1);
}
}
return res;
}
/**
* 检查表达式是否有括号,并且检查是否符合
* @param exp
* @return
*/
public static boolean checkExp(String exp) {
boolean res = true;
int index = exp.indexOf("(");
if (index != -1) {
int leftN = 0;
for (int i = index; i < exp.length(); i++) {
if (exp.charAt(i) == '(') {
leftN++;
}
else if (exp.charAt(i) == ')') {
leftN--;
if (leftN == -1) {
res = false;
break;
}
}
}
if (leftN > 0) {
res = false;
}
}
return res;
}
}
以上内容由PHP站长网【52php.cn】收集整理供大家参考研究 如果以上内容对您有帮助,欢迎收藏、点赞、推荐、分享。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
