计算器?不是非常简单吗?声明两个float型变量,再加上操作符,自动计算结果出来!
public static float calc(float a, float b, int operator) {
switch (operator) {
case 0:
// +
return a + b;
case 1:
// -
return a - b;
case 2:
// *
return a * b;
case 3:
// /
return a / b;
default:
// +
return a + b;
}
}
呵呵,这么简单,那就没必要写成文章了
这里要说的是:程序计算表达式的值,比如:1-2*3+5*9
就是简单两个变量就能完成的,要考虑运算符优先等级
好了,上代码吧
首先,得把表达式分割,按操作符来分割(此处没考虑小括号,思路是一样的)
/**将一条字符串整成字符数组*/
public ArrayList<String> toString(StringBuffer str2)
{
String str=str2.toString();
String temp = "";
ArrayList<String> list=new ArrayList<String>();
//str是原字符串,按操作符分割,存入数组ch中
for(int i=0;i<str.length();i++)
{
if(!"+".equals(str.substring(i,i+1))&&
!"/".equals(str.substring(i,i+1))&&
!"-".equals(str.substring(i,i+1))&&
!"*".equals(str.substring(i,i+1)))
{
temp=temp+str.substring(i,i+1);
}else//遇到了操作符
{
list.add(temp);
temp=str.substring(i,i+1);
list.add(temp);
temp="";
}
}
list.add(temp);
temp="";
return list;
}
接下来,要进行运算,其实实现方式有多种,我以前在看C/C++数据结构时,看过一个叫后辍表达式算法,觉得此方法甚好,所以,就用这种方式来实现
什么是后辍表达式?我们常见的表达式其中叫中辍表达式,这两者有什么区别呢?中辍表达式更直观点,后辍表达式更含蓄,但计算更方便,所以此处采用后辍算法
接下来就是重点:把中辍表达式转换成后辍表达式:
/**
* 将中辍表达式转换成后辍表达式
* 利用栈技术,后进先出
* 如果遇到的是操作符,就把当前的操作符与栈顶存的操作符作比较
* 如果当前的操作符优先等级高,就 入栈
* 如果当前的操作符与栈顶存的操作符优先等级相同,先出栈,再入栈
* 如果当前操作符优先等级低,就出栈,如果下一个还低,再出栈,直到栈底,或栈内 元素高于当前的
* */
public ArrayList<String> CenterToBehind(LinkedList<String> list)
{
ArrayList<String> resultList=new ArrayList<String>();//结果集
LinkedList<String> linkList=new LinkedList<String>();//操作符栈
Iterator<String> it = list.iterator();
while(it.hasNext())
{
String s=it.next();
if("+".equals(s)||"-".equals(s)||"*".equals(s)||"/".equals(s))
{
/**
* 如果是操作符,先看栈顶有没有操作符,如果没有,直接存入
* */
if(linkList.isEmpty())
{
linkList.push(s);//入栈
}
else {
/**
*当前的操作符的优先级与 存入的操作符比较
*如果当前的高,入栈
*3+2*5+2
*3 2 5 * +2+
*如果相等,先出栈,再入栈
*3*2+5
*3 2 * 5 +
*如果当前的低,弹出栈顶,再把当前的操作符入栈
* */
if(operStep(s)>operStep(linkList.getFirst()))
{
linkList.push(s);
}
else if(operStep(s)==operStep(linkList.getFirst())){
/**
* 如果取出的操作符与栈顶操作符优先等级相等
* 先将栈顶的操作符弹出
* 再将当前取出的操作符入栈
* */
resultList.add(linkList.pop());
linkList.push(s);
}
else {
while(!linkList.isEmpty())
{
/**
*
* */
if(operStep(s)>operStep(linkList.getFirst()))
break;
else {
if(operStep(s)==operStep(linkList.getFirst()))
{ resultList.add(linkList.pop());
linkList.push(s);
break;
}
else {
resultList.add(linkList.pop());
break;
}
}
}
linkList.push(s);
}
}
}
else {
resultList.add(s);
}
}
//将操作符中所有操作符存入到结果中
int i=0;
while(!linkList.isEmpty())
{
resultList.add(linkList.pop());
Log.i("i=",""+i);
i++;
}
return resultList;
}
/**
* 操作符比较
* */
public int operStep(String ch)
{
int i=1;
if("+".equals(ch)||"-".equals(ch))
{
i=1;
}
else if("*".equals(ch)||"/".equals(ch))
{
i=2;
}
return i;
}
后面的就简单了
/**
*计算
* 四则运算
* */
public double calc(BigDecimal a,BigDecimal b,int c)
{
//a,b为操作数,以为操作符
BigDecimal d=BigDecimal.valueOf(0);//计算结果
switch (c) {
case 1://+
d=a.add(b);
break;
case 2://-
d=a.subtract(b);
break;
case 3://*
d=a.multiply(b);
break;
case 4:///
if(b.doubleValue()!=0)
{
d=a.divide(b,BigDecimal.ROUND_HALF_UP);
}
else
{
tv.setText("除数不能为0");
return 0;
}
break;
}
return Double.parseDouble(d.toString());
}
str.append(et.getText().toString());
BigDecimal x1=BigDecimal.valueOf(0);
BigDecimal x2=BigDecimal.valueOf(0);
// //转换成数组
String str=et.getText().toString();
list=mySplit(str);
// //中辍转后辍
link=CenterToBehind(list);
//计算
/**
* 从结果中取数字,如果取的是操作符,就将前两个数作运算,
* 并将结果存入到第一个操作数中
* */
//先声明一个临时存结果的ArrayList
ArrayList<Double> doubles=new ArrayList<Double>();
int flag=0;
if(link.size()>0)
{
for(int i=0;i<link.size();i++)
{
/**
* 如果遇到的是操作符,就把存结果的前两个数作运算,
* 并移除前两个操作数,
* 再把计算的结果存入到结果中
* 同时要移动指针,向上移一位,因为减了两个,增加了一个
* */
if("+".equals(link.get(i)))
{
x1=BigDecimal.valueOf(doubles.get(flag-2));
x2=BigDecimal.valueOf(doubles.get(flag-1));
x1=BigDecimal.valueOf(calc(x1, x2, 1));
doubles.remove(flag-1);
doubles.remove(flag-2);
doubles.add(Double.valueOf(x1.toString()));
flag--;
}
else if("-".equals(link.get(i)))
{
x1=BigDecimal.valueOf(doubles.get(flag-2));
x2=BigDecimal.valueOf(doubles.get(flag-1));
x1=BigDecimal.valueOf(calc(x1, x2, 2));
doubles.remove(flag-1);
doubles.remove(flag-2);
doubles.add(Double.valueOf(x1.toString()));
flag--;
}
else if("*".equals(link.get(i)))
{
x1=BigDecimal.valueOf(doubles.get(flag-2));
x2=BigDecimal.valueOf(doubles.get(flag-1));
x1=BigDecimal.valueOf(calc(x1, x2, 3));
doubles.remove(flag-1);
doubles.remove(flag-2);
doubles.add(Double.valueOf(x1.toString()));
flag--;
}
else if("/".equals(link.get(i)))
{
x1=BigDecimal.valueOf(doubles.get(flag-2));
x2=BigDecimal.valueOf(doubles.get(flag-1));
x1=BigDecimal.valueOf(calc(x1, x2, 4));
doubles.remove(flag-1);
doubles.remove(flag-2);
doubles.add(Double.valueOf(x1.toString()));
flag--;
}
else {
/**
* 如果遇到的不是操作符
* 那么就直接把这个字符串转换成数字
* 再存入到待计算的结果集中
* */
flag++;
x2=BigDecimal.valueOf(Double.parseDouble(link.get(i)));
doubles.add(Double.valueOf(x2.toString()));
}
}
}
tv.setText("计算结果:\n"+x1.toString());
完整代码: 请点击我下载