android 简易计算器

//  日期:2014/9/26

//  首先,人们的输入习惯为中缀表达式。为了便于计算,程序会将中缀表达式会转换为后缀表达式


//  目前软件还存在
//  1.输入运算数和运算符不匹配时,崩溃的现象。(如:只输入一个操作数)
//  2.一个数字中重复输入两个小数点。(如4.5.6)
//  这两个重大的bug,后续会继续修改


//  只有一种布局。这也会在后续考虑完善。
//  若有其他不完善的地方,请指正。(╯▽╰)


package com.example.countea;

import android.os.Bundle;                                     //不太明白到底是啥
import android.app.Activity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

import android.widget.Toast;                                  // 显示版权信息
import java.util.Iterator;                                    // 迭代器
import java.util.LinkedList;                                  // 双向列表

public class MainActivity extends Activity {
	private EditText content;
	private EditText operaline;
	private Double first_num  = 0.0;                           // 第一个操作数
	private Double sec_num    = 0.0;                           // 第二个操作数
	//无法设置bool型变量?????
	private static int equal_flg = 0;                          // 等号的状态:FALSE表示未按过等号,TRUE表示已经按过等号
	private double negative_mark = 0;                          // 正负数标记
	LinkedList<String> Infix = new LinkedList<String>();       // 对content进行解析,即存放中缀表达式的链表
	LinkedList<String> Suffix = new LinkedList<String>();      // 存放后缀表达式的链表
	LinkedList<Double> Suffix_Num = new LinkedList<Double>();  // 存放后缀表达式的数字链表
	LinkedList<String> OP = new LinkedList<String>();          // 1.作为临时存放运算符的链表;2.存放后缀表达式的运算符

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		
		// 处理"c"清屏按钮功能
		Button clear = (Button) findViewById(R.id.clear);
		clear.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) 
			{
				// TODO Auto-generated method stub
				content = (EditText) findViewById(R.id.content);
				content.setText("");
				equal_flg = 0;
				
				first_num = 0.0;
				sec_num = 0.0;
				OP.clear();
				Suffix.clear();
				Suffix_Num.clear();
				operaline.setText("");
				operaline.setSelection(operaline.getText().length());
			}
		});
		
		// 处理CE删除当前操作按钮功能
		Button current_clear = (Button) findViewById(R.id.current_clear);
	    current_clear.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) 
			{
				// TODO Auto-generated method stub
				content = (EditText) findViewById(R.id.content);
				content.setText("");
				equal_flg = 0;

				first_num = 0.0;
				sec_num = 0.0;
				OP.clear();
				Suffix.clear();
				Suffix_Num.clear();
			}
		});

		// 处理back退格按钮功能
		Button back = (Button) findViewById(R.id.back);
		back.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				content = (EditText) findViewById(R.id.content);
				String str = content.getText().toString();
				if (content.getText().length() != 0)
					content.setText(str.substring(0, str.length() - 1));
				    content.setSelection(content.getText().length());  //暂时不知道有什么用,若编辑框为空则无需处理,验证是否会导致异常退出
			}
		});

		// 考虑对符号键和数字键是否需要分开实现
		// 实现对"0123456789.+-*/()"按钮的监听;而对"="按钮的监听则采用匿名内部类的方法在onCreate()方法体内进行
		OnClickListener mylistener = new OnClickListener() 
		{
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Button num_btn = (Button) v;
				content = (EditText) findViewById(R.id.content);

				//  储存界面运算式
				String content_str = content.getText().toString();
				
				//  当已经有一次运算时,再次按“数字键”清除上次的结果
				if((1==equal_flg)/*&&(num_btn.getText().toString().equals("1")
						||num_btn.getText().toString().equals("2")
						||num_btn.getText().toString().equals("3")
						||num_btn.getText().toString().equals("4")
						||num_btn.getText().toString().equals("5")
						||num_btn.getText().toString().equals("6")
						||num_btn.getText().toString().equals("7")
						||num_btn.getText().toString().equals("8")
						||num_btn.getText().toString().equals("9")
						||num_btn.getText().toString().equals("0"))*/)
				{
					content.setText("0");
					content.setSelection(content.getText().length());
					Toast.makeText(MainActivity.this,"还真执行了!", Toast.LENGTH_LONG).show();
					equal_flg=0;		
				}
				
				// 重复输入运算符、括号或者“.”的处理
				if(("+".equals(content_str.substring(content_str.length()-1,content_str.length()))
						||"-".equals(content_str.substring(content_str.length()-1,content_str.length()))
						||"*".equals(content_str.substring(content_str.length()-1,content_str.length()))
						||"/".equals(content_str.substring(content_str.length()-1,content_str.length()))
						||".".equals(content_str.substring(content_str.length()-1,content_str.length())))&&((num_btn.getText().toString().equals("+")
						||num_btn.getText().toString().equals("-")
						||num_btn.getText().toString().equals("*")
						||num_btn.getText().toString().equals("/")
						||num_btn.getText().toString().equals("."))))
				{
					content_str=content_str.substring(0, content_str.length()-1);
					//Toast.makeText(MainActivity.this,"手抖了吗?", Toast.LENGTH_LONG).show();
				}	
				
				//  重复按“.”的处理
				/*if(num_btn.getText().toString().equals("."))
				{
					// 如果界面只有数字,则改变当前数字的符号
					if("0"!=content_str)
					{
						judge_str = turn_mark(judge_str);					
						content.setText(judge_str);
						content.setSelection(content.getText().length());
					 // Toast.makeText(MainActivity.this,"GET", Toast.LENGTH_LONG).show();
					}
				}*/				
				
				// 不实现拼接
				// 当前数据为0,下次输入为非0数字或括号
				if("0".equals(content.getText().toString())
						&&!(num_btn.getText().toString().equals("+"))
						&&!(num_btn.getText().toString().equals("-"))
						&&!(num_btn.getText().toString().equals("*"))
						&&!(num_btn.getText().toString().equals("/"))
						&&!(num_btn.getText().toString().equals(".")))
				{
					// 强制转换测试是否有危险??????
					content_str = (String) num_btn.getText();
					//Toast.makeText(MainActivity.this,num_btn.getText(), Toast.LENGTH_LONG).show();
				}
				
				// 实现拼接
				// 当前数据为0且下次输入为运算符或点号
				else
				{
					content_str += num_btn.getText();
					//Toast.makeText(MainActivity.this,content_str, Toast.LENGTH_LONG).show();
				}
				content.setText(content_str);
				content.setSelection(content.getText().length());
			}
		};
		
		// 无需特别处理的数字和符号按钮
		Button num1 = (Button) findViewById(R.id.num_1);
		num1.setOnClickListener(mylistener);
		Button num2 = (Button) findViewById(R.id.num_2);
		num2.setOnClickListener(mylistener);
		Button num3 = (Button) findViewById(R.id.num_3);
		num3.setOnClickListener(mylistener);
		Button num4 = (Button) findViewById(R.id.num_4);
		num4.setOnClickListener(mylistener);
		Button num5 = (Button) findViewById(R.id.num_5);
		num5.setOnClickListener(mylistener);
		Button num6 = (Button) findViewById(R.id.num_6);
		num6.setOnClickListener(mylistener);
		Button num7 = (Button) findViewById(R.id.num_7);
		num7.setOnClickListener(mylistener);
		Button num8 = (Button) findViewById(R.id.num_8);
		num8.setOnClickListener(mylistener);
		Button num9 = (Button) findViewById(R.id.num_9);
		num9.setOnClickListener(mylistener);
		Button point = (Button) findViewById(R.id.point);
		point.setOnClickListener(mylistener);
		Button left = (Button) findViewById(R.id.left);
		left.setOnClickListener(mylistener);
		Button right = (Button) findViewById(R.id.right);
		right.setOnClickListener(mylistener);
		Button plus = (Button) findViewById(R.id.plus);
		plus.setOnClickListener(mylistener);
		Button subtract = (Button) findViewById(R.id.subs);
		subtract.setOnClickListener(mylistener);
		Button multiply = (Button) findViewById(R.id.multiply);
		multiply.setOnClickListener(mylistener);
		Button divide = (Button) findViewById(R.id.division);
		divide.setOnClickListener(mylistener);

		
		// 对按钮0的处理
		Button num0 = (Button) findViewById(R.id.num_0);
		num0.setOnClickListener(new OnClickListener() 
		{
			@Override
			public void onClick(View v) 
			{
				content = (EditText) findViewById(R.id.content);
				// 当前编辑框中的值为0
				if ("0".equals(content.getText().toString())||""== content.getText().toString())
				{
				  content.setText("0");
				}
				// 编辑框已有非0数据
				else
				{
				   String str = content.getText().toString();
			       str += "0";
			       content.setText(str);
				}
				content.setSelection(content.getText().length());
				// Toast.makeText(MainActivity.this,"GET", Toast.LENGTH_LONG).show();
			} 
		});
		
		// 对“-/+”的处理
		Button mark_sign = (Button) findViewById(R.id.mark_sign);
		mark_sign.setOnClickListener(new OnClickListener() 
		{
			@Override
			public void onClick(View v) 
			{
				
				content = (EditText) findViewById(R.id.content);
				String judge_str = content.getText().toString();
				
				// 如果界面只有数字,则改变当前数字的符号
				if("0"!=judge_str&&((-1==judge_str.indexOf("+"))
						||(-1==judge_str.indexOf("-")))
						||(-1==judge_str.indexOf("*"))
						||(-1==judge_str.indexOf("/"))
						||(-1==judge_str.indexOf("("))
						||(-1==judge_str.indexOf(")")))
				{
					judge_str = turn_mark(judge_str);					
					content.setText(judge_str);
					content.setSelection(content.getText().length());
				 // Toast.makeText(MainActivity.this,"GET", Toast.LENGTH_LONG).show();
				}
			} 
		});
		// 实现"="按钮的功能
		Button equal = (Button) findViewById(R.id.equal);
		equal.setOnClickListener(new OnClickListener() 
		{
			@Override
			public void onClick(View v) 
			{
				// TODO Auto-generated method stub
				content = (EditText) findViewById(R.id.content);
				operaline = (EditText) findViewById(R.id.operatline);
				// str_Infix为待转换的中缀表达式
				String str_Infix = content.getText().toString();
				// 友好的界面提示处理
				String equate = str_Infix;
				equate += "=";
				operaline.setText(equate);
				operaline.setSelection(content.getText().length());
				// 调用Analysis函数对content进行解析
				MainActivity.this.Analysis(str_Infix);            
				System.out.println(Infix);
				// 至此,中缀表达式已存放到Infix链表中

				Iterator<String> it = Infix.iterator();
				while (it.hasNext()) 
				{      
					String tmp_str = it.next();
					if (isNum(tmp_str)) 
					{
			        // 如果是数字或小数点则直接进入Suffix链表;
						Suffix.addLast(tmp_str);
					}
					// 如果不是数字或小数点的话;
					else 
					{
						int OP_level = OP.isEmpty() ? 0 : getLevel(OP.getLast());
						// tmp_str比OP的顶运算符优先级高则入OP
						if (getLevel(tmp_str) > OP_level) 
						{
							OP.addLast(tmp_str);
						}
						// tmp_str比OP的顶运算符优先级低
						else 
						{
							// tmp_str为")",则将OP一直出栈直到遇到"("
							if (getLevel(tmp_str) == -1) 
							{
								String temp_OP = OP.removeLast();
								while (getLevel(temp_OP) != -2) {
									Suffix.addLast(temp_OP);
									temp_OP = OP.removeLast();
								}
							}
							// tmp_str为"(",则直接入OP
							else if (getLevel(tmp_str) == -2) 
							{
								OP.addLast(tmp_str);
							}
							// tmp_str比OP_level优先级低又不是"(" ")",
							// 则OP一直出栈直到OP为空或tmp_str比OP_level优先级高
							else 
							{
								String str2 = OP.removeLast();
								while (getLevel(str2) >= OP_level) 
								{
									Suffix.addLast(str2);
									if (OP.isEmpty()) 
									{
										break;
									}
									str2 = OP.removeLast();
								}
								OP.addLast(tmp_str);
							}
						}
					}
				}
				Infix.clear();// 清空Infix链表
				// OP中剩余的元素出OP进入Suffix
				while (!OP.isEmpty()) 
				{
					Suffix.addLast(OP.removeLast());
				}
				System.out.println(Suffix);
				// 至此,中缀表达式已全部转化为后缀表达式Suffix

				// 后缀表达式的计算过程???未指定操作数时 默认为0
				while (!(Suffix.isEmpty())) 
				{
					String count_str = Suffix.removeFirst();
					if (isOP(count_str)) 
					{
						char compare_ch = count_str.charAt(0);
						first_num = Suffix_Num.removeLast();
						sec_num = Suffix_Num.removeLast();
						switch (compare_ch) {
						case '*':
							Suffix_Num.addLast(sec_num * first_num);
							break;
						case '/':
							// 测试注意除数和被除数的顺序
							if (first_num != 0) 
							{
								Suffix_Num.addLast(sec_num / first_num);
								break;
							} else 
							{
								content = (EditText) findViewById(R.id.content);
								// ?????无法再编辑框内,设置提示
								content.setText("∞");
								content.setSelection(content.getText().length());
							}
						case '+':
							Suffix_Num.addLast(sec_num + first_num);
							break;
						case '-':
							Suffix_Num.addLast(sec_num - first_num);
							break;
						}
					} 
					else 
					{
						Suffix_Num.addLast(Double.parseDouble(count_str));
					}
				}
				// 至此,求得的结果已在Suffix_Num列表中
				
				// 这部分的逻辑为 result 存放从Suffix_Num列表中取出的数据,处理结果后显示到界面上。
				Double result=Suffix_Num.removeFirst();
				String res_str=Double.toString(result);
				
				if("0".equals(res_str.substring(res_str.length()-1,res_str.length())))
				{
				  if(".".equals(res_str.substring(res_str.length()-2,res_str.length()-1)))
				  {
					 res_str=res_str.substring(0,res_str.length()-2);
					 //Toast.makeText(MainActivity.this,res_str, Toast.LENGTH_LONG).show();
				  };
				};
			    content.setText(res_str);
			    content.setSelection(content.getText().length());
			    equal_flg = 1;
			    if("-".equals(res_str.substring(0,1)))
					res_str=turn_mark(res_str);
			}
		});
		// 操作数清空?????android有自动释放机制?
		first_num = 0.0;
		sec_num = 0.0;
		OP.clear();
		Suffix.clear();
		Suffix_Num.clear();
	}

	// 自定义isNum()方法来检测元素是否为数值
	public boolean isNum(String str) {
		int num = 0;
		for (int i = 0; i < str.length(); i++) {
			String strr = str.substring(i, i + 1);
			if (strr.equals("0") || strr.equals("1") || strr.equals("2")
					|| strr.equals("3") || strr.equals("4") || strr.equals("5")
					|| strr.equals("6") || strr.equals("7") || strr.equals("8")
					|| strr.equals("9") || strr.equals("."))
				num = num + 1;
		}
		if (num == str.length())
			return true;
		else
			return false;
	}

	// 自定义isOP()方法来检测Suffix列表的元素是否为运算符
	public boolean isOP(String strr) {
		if (strr.equals("+") || strr.equals("-") || strr.equals("*")
				|| strr.equals("/"))
			return true;
		else
			return false;
	}

	// 定义运算符的等级
	public int getLevel(String str) {
		if (str.equals("*") || str.equals("/")) {
			return 2;
		} else if (str.equals("+") || str.equals("-")) {
			return 1;
		} else if (str.equals("(")) {
			return -2;
		} else if (str.equals(")")) {
			return -1;
		} else {
			return 0;
		}
	}
    
	// 改变正负号
	public String turn_mark(String str) 
	{
		String temp = "(";
		temp += "-";
		temp += str;
		temp += ")";
		str = temp;
		return str;
	}
	
	// 实现对编辑框内容以数字和操作符分开储存
	public void Analysis(String str) {
		String sub = "";

		for (int i = 0; i < str.length(); i++) 
		{
			// 用substring遍历需要解析的数组
			String strr = str.substring(i, i + 1);
			if (isNum(strr)) 
			{
				sub += strr;
			}
			else 
			{
				if (sub != "")
				{
					Infix.addLast(sub);   // 首先sub进Infix
					sub = "";             // 将sub清空
				}
				Infix.addLast(strr);      // "+-*/" "(" ")" 则直接进Infix表
			}
		}
		// ?????测试for下面的IF是否是因为循环无法判断最后一个数
		if (isNum(str.substring(str.length() - 1))) {
			Infix.addLast(sub);           // 首先sub进Infix
			sub = "";                     // 将sub清空
		}
		
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) 
	{
		/*
		 * // Inflate the menu; this adds items to the action bar if it is
		 * present. getMenuInflater().inflate(R.menu.main, menu);
		 */
		menu.add(0, 1, 1, "退出");
		menu.add(0, 2, 2, "关于");
		menu.add(0, 3, 3, "帮助");
		return super.onCreateOptionsMenu(menu);
		/* return true; */
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		//finish();
		if (item.getItemId() == 2) 
		{
			// 利用Toast来显示提示信息
			Toast.makeText(MainActivity.this,"作者:歡   联系:cdch@gmail.com", Toast.LENGTH_LONG).show();
		}
		if (item.getItemId() == 3) 
		{
			// 利用Toast来显示提示信息
			Toast.makeText(MainActivity.this,"适用于一般算数运算!", Toast.LENGTH_LONG).show();
		}
		
		return super.onOptionsItemSelected(item);
	};

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值