计算器的实现

来源:互联网 发布:霸道总裁小说知乎 编辑:程序博客网 时间:2024/06/05 16:48

  计算器?不是非常简单吗?声明两个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);//计算/** * 从结果中取数字,如果取的是操作符,就将前两个数作运算, * 并将结果存入到第一个操作数中 * *///先声明一个临时存结果的ArrayListArrayList<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());

完整代码:请点击我下载

0 0
原创粉丝点击