计算器的实现

  计算器?不是非常简单吗?声明两个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());

完整代码: 请点击我下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ytmfdw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值