第一部分布局设计
1.布局图片

2.布局代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"android:background="#ff808080"> <!-- 结果显示框 --><EditText android:id="@+id/input"android:layout_width="fill_parent"android:layout_height="wrap_content"android:cursorVisible="false"android:gravity="right"android:editable = "false"android:text="0"                               />    <!-- 接下去采TableRow的格式进行布局设计 --><TableRowandroid:layout_width="fill_parent"android:layout_height="wrap_content"><!-- 用于显示存储结果 --><TextView android:id="@+id/M"android:layout_width="53sp"android:layout_height="wrap_content"android:text="  MEM :"                 /><!-- 默认显示字符串0 --><TextView android:id="@+id/mem"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="0"                       /> </TableRow>  <TableRowandroid:layout_width="fill_parent"android:layout_height="wrap_content">       <!-- 显示当前是角度还是弧度,默认是角度 --><TextView android:id="@+id/_drg"android:layout_width="53sp"android:layout_height="wrap_content"android:text="   DEG"                 /><!-- 清除存储结果 --><Button android:id="@+id/mc"android:text="MC"android:layout_width="106sp"android:layout_height="wrap_content"   /> <!-- 清除输出窗口的所有内容 --><Button android:id="@+id/c"android:text="C"android:layout_width="fill_parent"android:layout_height="wrap_content"   />                                                                                                  </TableRow>                      <TableRowandroid:layout_width="fill_parent"android:layout_height="wrap_content">  <!-- 在角度和弧度之间切换 --><Button android:id="@+id/drg"android:text="DRG"android:layout_width="53sp"android:layout_height="wrap_content" /> <!-- 正弦计算 --><Button android:id="@+id/sin"android:text="sin"android:layout_width="53sp" android:layout_height="wrap_content" /><!-- 余弦计算 --><Button android:id="@+id/cos"android:text="cos"android:layout_width="53sp"android:layout_height="wrap_content" /><!-- 正切计算 --><Button android:id="@+id/tan"android:text="tan"android:layout_width="53sp"android:layout_height="wrap_content" /><!-- 阶乘计算 --><Button android:id="@+id/factorial"android:text="n!"android:layout_width="53sp"android:layout_height="wrap_content" /><!-- 退格键 --><Button android:id="@+id/bksp"android:text="Bksp"android:layout_width="53sp"android:layout_height="wrap_content" />                                                                                                              </TableRow>                  <TableRowandroid:layout_width="fill_parent"android:layout_height="wrap_content">  <!-- 数字7 --><Button android:id="@+id/seven"android:text="7"android:layout_width="53sp" android:layout_height="wrap_content" /><!-- 数字8 --><Button android:id="@+id/eight"android:text="8"android:layout_width="53sp"android:layout_height="wrap_content" />    <!-- 数字9 --><Button android:id="@+id/nine"android:text="9"android:layout_width="53sp"android:layout_height="wrap_content" />    <!-- 除号 --><Button android:id="@+id/divide"android:text="÷"android:layout_width="53sp"android:layout_height="wrap_content" /><!-- 左括号 -->     <Button android:id="@+id/left"android:text="("android:layout_width="53sp"android:layout_height="wrap_content" /><!-- 右括号 -->   <Button android:id="@+id/right"android:text=")"android:layout_width="53sp"android:layout_height="wrap_content" />                                                                                           </TableRow>        <TableRowandroid:layout_width="fill_parent"android:layout_height="wrap_content">  <!-- 数字4 --><Button android:id="@+id/four"android:text="4"android:layout_width="53sp" android:layout_height="wrap_content" /><!-- 数字5 --><Button android:id="@+id/five"android:text="5"android:layout_width="53sp"android:layout_height="wrap_content" /><!-- 数字6 -->    <Button android:id="@+id/six"android:text="6"android:layout_width="53sp"android:layout_height="wrap_content" /><!-- 乘号 -->    <Button android:id="@+id/mul"android:text="×"android:layout_width="53sp"android:layout_height="wrap_content" /><!-- 开方 -->  <Button android:id="@+id/sqrt"android:text="√"android:layout_width="53sp"android:layout_height="wrap_content" /><!-- 乘方 --><Button android:id="@+id/square"android:text="^"android:layout_width="53sp"android:layout_height="wrap_content" />                                                                                                               </TableRow>            <TableRowandroid:layout_width="fill_parent"android:layout_height="wrap_content"><!-- 数字1 -->   <Button android:id="@+id/one"android:text="1"android:layout_width="53sp" android:layout_height="wrap_content" /><!-- 数字2 --><Button android:id="@+id/two"android:text="2"android:layout_width="53sp"android:layout_height="wrap_content" /><!-- 数字3 -->    <Button android:id="@+id/three"android:text="3"android:layout_width="53sp"android:layout_height="wrap_content" /><!-- 减号 -->    <Button android:id="@+id/sub"android:text="-"android:layout_width="53sp"android:layout_height="wrap_content" /><!-- 对数 -->     <Button android:id="@+id/log"android:text="log"android:layout_width="53sp"android:layout_height="wrap_content" /><!-- 自然对数 --><Button android:id="@+id/ln"android:text="ln"android:layout_width="53sp" android:layout_height="wrap_content" />                                                                                                   </TableRow>         <TableLayout android:layout_width="fill_parent"android:layout_height="57sp">                      <TableRowandroid:layout_width="fill_parent"android:layout_height="wrap_content"><!-- 数字0 -->  <Button android:id="@+id/zero"android:text="0"android:layout_width="53sp" android:layout_height="wrap_content" /><!-- 小数点 --><Button android:id="@+id/dot"android:text="."android:layout_width="53sp"android:layout_height="wrap_content" /><!-- 等号 --><Button android:id="@+id/equal"android:text="="android:layout_width="53sp"android:layout_height="wrap_content" /><!-- 加号 -->     <Button android:id="@+id/add"android:text="+"android:layout_width="53sp"android:layout_height="wrap_content" /><!-- 退出计算器 --><Button android:id="@+id/exit"android:text="exit"android:layout_width="106sp"android:layout_height="wrap_content" />                                                                                                      </TableRow>  </TableLayout>    <TableRowandroid:layout_width="fill_parent"android:layout_height="wrap_content"><!-- 用于提示,告诉用户如何使用计算器的一些功能等 --><TextView android:id="@+id/T"android:layout_width="45sp"android:layout_height="wrap_content"android:text="提示:"                 /><TextView android:id="@+id/tip"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="欢迎使用!"                 /> </TableRow>
</LinearLayout>

第二部分逻辑代码

package com.supermario.jisuanqi;//import java.text.NumberFormat;
import java.text.DecimalFormat;
import android.app.Activity;
import android.os.Bundle;
import android.widget.*;
import android.util.Log;
import android.view.View.*;
import android.view.*;
import java.util.*;public class Jisuanqi extends Activity
{//0~9十个按键private Button[] btn = new Button[10];//显示器,用于显示输出结果private EditText input;//显示器下方的记忆器,用于记录上一次计算结果private TextView mem;//三角计算时标志显示:角度还是弧度private TextView _drg;//小提示,用于加强人机交互的弱检测、提示 private TextView tip;                            private Buttondiv, mul, sub, add, equal,            // ÷ × - + =sin, cos, tan, log, ln,               //函数sqrt, square, factorial, bksp,      //根号  平方  阶乘   退格left, right, dot, exit, drg,          //(     )  .  退出     角度弧度控制键mc, c;                                // mem清屏键    input清屏键//保存原来的算式样子,为了输出时好看,因计算时,算式样子被改变public String str_old;//变换样子后的式子public String str_new;//输入控制,true为重新输入,false为接着输入public boolean vbegin = true;//控制DRG按键,true为角度,false为弧度public boolean drg_flag = true;//π值:3.14public double pi=4*Math.atan(1);//true表示正确,可以继续输入;false表示有误,输入被锁定public boolean tip_lock = true;//判断是否是按=之后的输入,true表示输入在=之前,false反之public boolean equals_flag = true;  public void onCreate(Bundle icicle){super.onCreate(icicle);setContentView(R.layout.main);//获取界面元素input = (EditText)findViewById(R.id.input);mem = (TextView)findViewById(R.id.mem);tip = (TextView)findViewById(R.id.tip); _drg = (TextView)findViewById(R.id._drg);btn[0] = (Button)findViewById(R.id.zero);btn[1] = (Button)findViewById(R.id.one);btn[2] = (Button)findViewById(R.id.two);btn[3] = (Button)findViewById(R.id.three);btn[4] = (Button)findViewById(R.id.four);btn[5] = (Button)findViewById(R.id.five);btn[6] = (Button)findViewById(R.id.six);btn[7] = (Button)findViewById(R.id.seven);btn[8] = (Button)findViewById(R.id.eight);btn[9] = (Button)findViewById(R.id.nine);div = (Button)findViewById(R.id.divide);mul = (Button)findViewById(R.id.mul);sub = (Button)findViewById(R.id.sub);add = (Button)findViewById(R.id.add);equal = (Button)findViewById(R.id.equal);sin = (Button)findViewById(R.id.sin);cos = (Button)findViewById(R.id.cos);tan = (Button)findViewById(R.id.tan);log = (Button)findViewById(R.id.log);ln = (Button)findViewById(R.id.ln);sqrt = (Button)findViewById(R.id.sqrt);square = (Button)findViewById(R.id.square);factorial = (Button)findViewById(R.id.factorial);bksp = (Button)findViewById(R.id.bksp);left = (Button)findViewById(R.id.left);right = (Button)findViewById(R.id.right);dot = (Button)findViewById(R.id.dot);exit = (Button)findViewById(R.id.exit);drg = (Button)findViewById(R.id.drg);mc = (Button)findViewById(R.id.mc);c = (Button)findViewById(R.id.c);//为数字按键绑定监听器for(int i = 0; i < 10; ++i) {btn[i].setOnClickListener(actionPerformed);}//为+-x÷等按键绑定监听器div.setOnClickListener(actionPerformed);mul.setOnClickListener(actionPerformed);sub.setOnClickListener(actionPerformed);add.setOnClickListener(actionPerformed);equal.setOnClickListener(actionPerformed);sin.setOnClickListener(actionPerformed);cos.setOnClickListener(actionPerformed);tan.setOnClickListener(actionPerformed);log.setOnClickListener(actionPerformed);ln.setOnClickListener(actionPerformed);sqrt.setOnClickListener(actionPerformed);square.setOnClickListener(actionPerformed);    factorial.setOnClickListener(actionPerformed);bksp.setOnClickListener(actionPerformed);    left.setOnClickListener(actionPerformed);right.setOnClickListener(actionPerformed);dot.setOnClickListener(actionPerformed);    exit.setOnClickListener(actionPerformed);drg.setOnClickListener(actionPerformed);mc.setOnClickListener(actionPerformed);    c.setOnClickListener(actionPerformed);}/** 键盘命令捕捉*///命令缓存,用于检测输入合法性String[] Tipcommand = new String[500]; //Tipcommand的指针int tip_i = 0;         private OnClickListener actionPerformed = new OnClickListener() {public void onClick(View v) {//按键上的命令获取String command = ((Button)v).getText().toString();//显示器上的字符串String str = input.getText().toString();  //检测输入是否合法if(equals_flag == false && "0123456789.()sincostanlnlogn!+-×÷√^".indexOf(command) != -1) {//检测显示器上的字符串是否合法if(right(str)) {if("+-×÷√^)".indexOf(command) != -1) {for(int i =0 ; i < str.length(); i++) {Tipcommand[tip_i] = String.valueOf(str.charAt(i));tip_i++;}vbegin = false;}} else {input.setText("0");vbegin = true;tip_i = 0;tip_lock = true;tip.setText("欢迎使用!");}equals_flag = true;}if(tip_i > 0)TipChecker(Tipcommand[tip_i-1] , command);else if(tip_i == 0) {TipChecker("#" , command);}if("0123456789.()sincostanlnlogn!+-×÷√^".indexOf(command) != -1 && tip_lock) {Tipcommand[tip_i] = command;tip_i++;} //若输入正确,则将输入信息显示到显示器上if("0123456789.()sincostanlnlogn!+-×÷√^".indexOf(command) != -1 && tip_lock) { //共25个按键print(command);//若果点击了“DRG”,则切换当前弧度角度制,并将切换后的结果显示到按键上方。} else if(command.compareTo("DRG") == 0 && tip_lock) {if(drg_flag == true) {drg_flag = false;_drg.setText("   RAD");} else {drg_flag = true;_drg.setText("   DEG");}//如果输入时退格键,并且是在按=之前} else if(command.compareTo("Bksp") == 0 && equals_flag) {//一次删除3个字符if(TTO(str) == 3) {if(str.length() > 3)input.setText(str.substring(0, str.length() - 3)); else if(str.length() == 3) {input.setText("0");   vbegin = true;tip_i = 0;tip.setText("欢迎使用!");}//依次删除2个字符} else if(TTO(str) == 2) {if(str.length() > 2)input.setText(str.substring(0, str.length() - 2)); else if(str.length() == 2) {input.setText("0");   vbegin = true;tip_i = 0;tip.setText("欢迎使用!");}//依次删除一个字符} else if(TTO(str) == 1) {//若之前输入的字符串合法则删除一个字符if(right(str)) {if(str.length() > 1)input.setText(str.substring(0, str.length() - 1)); else if(str.length() == 1) {input.setText("0");   vbegin = true;tip_i = 0;tip.setText("欢迎使用!");}//若之前输入的字符串不合法则删除全部字符} else {input.setText("0");   vbegin = true;tip_i = 0;tip.setText("欢迎使用!");}}if(input.getText().toString().compareTo("-") == 0 || equals_flag == false) {input.setText("0");vbegin = true;tip_i = 0;tip.setText("欢迎使用!");}tip_lock = true;if(tip_i > 0)tip_i--;//如果是在按=之后输入退格键} else if(command.compareTo("Bksp") == 0 && equals_flag ==false) {//将显示器内容设置为0input.setText("0");vbegin = true;tip_i = 0;tip_lock = true;tip.setText("欢迎使用!");//如果输入的是清除键} else if(command.compareTo("C") == 0) {//将显示器内容设置为0input.setText("0");//重新输入标志置为truevbegin = true;//缓存命令位数清0tip_i = 0;//表明可以继续输入tip_lock = true;//表明输入=之前equals_flag = true;tip.setText("欢迎使用!");//如果输入的是”MC“,则将存储器内容清0} else if(command.compareTo("MC") == 0) {mem.setText("0");//如果按”exit“则退出程序} else if(command.compareTo("exit") == 0) {System.exit(0);//如果输入的是=号,并且输入合法} else if(command.compareTo("=") == 0 && tip_lock && right(str) && equals_flag) {tip_i = 0;//表明不可以继续输入tip_lock = false;//表明输入=之后equals_flag = false;//保存原来算式样子str_old = str;//替换算式中的运算符,便于计算str = str.replaceAll("sin", "s");str = str.replaceAll("cos", "c");str = str.replaceAll("tan", "t");str = str.replaceAll("log", "g");str = str.replaceAll("ln", "l");str = str.replaceAll("n!", "!");//重新输入标志设置truevbegin = true;//将-1x转换成-str_new = str.replaceAll("-", "-1×");//计算算式结果new calc().process(str_new);}//表明可以继续输入tip_lock = true;}};//向input输出字符private void print(String str) {//清屏后输出if(vbegin)input.setText(str);//在屏幕原str后增添字符elseinput.append(str);vbegin = false;}  /** 判断一个str是否是合法的,返回值为true、false* 只包含0123456789.()sincostanlnlogn!+-×÷√^的是合法的str,返回true* 包含了除0123456789.()sincostanlnlogn!+-×÷√^以外的字符的str为非法的,返回false*/private boolean right(String str) {int i = 0;for(i = 0;i < str.length();i++) {if(str.charAt(i)!='0' && str.charAt(i)!='1' && str.charAt(i)!='2' && str.charAt(i)!='3' && str.charAt(i)!='4' && str.charAt(i)!='5' && str.charAt(i)!='6' && str.charAt(i)!='7' && str.charAt(i)!='8' && str.charAt(i)!='9' && str.charAt(i)!='.' && str.charAt(i)!='-' &&str.charAt(i)!='+' && str.charAt(i)!='×' && str.charAt(i)!='÷' &&str.charAt(i)!='√' && str.charAt(i)!='^' && str.charAt(i)!='s' &&str.charAt(i)!='i' && str.charAt(i)!='n' && str.charAt(i)!='c' &&str.charAt(i)!='o' && str.charAt(i)!='t' && str.charAt(i)!='a' &&str.charAt(i)!='l' && str.charAt(i)!='g' && str.charAt(i)!='(' &&str.charAt(i)!=')' && str.charAt(i)!='!') break;}if(i == str.length()) {return true;} else {return false;}}/** 检测函数,返回值为3、2、1  表示应当一次删除几个?  Three+Two+One = TTO* 为Bksp按钮的删除方式提供依据* 返回3,表示str尾部为sin、cos、tan、log中的一个,应当一次删除3个* 返回2,表示str尾部为ln、n!中的一个,应当一次删除2个* 返回1,表示为除返回3、2外的所有情况,只需删除一个(包含非法字符时要另外考虑:应清屏)*/private int TTO(String str) {  if((str.charAt(str.length() - 1) == 'n' && str.charAt(str.length() - 2) == 'i' &&str.charAt(str.length() - 3) == 's') ||(str.charAt(str.length() - 1) == 's' && str.charAt(str.length() - 2) == 'o' &&str.charAt(str.length() - 3) == 'c') ||(str.charAt(str.length() - 1) == 'n' && str.charAt(str.length() - 2) == 'a' &&str.charAt(str.length() - 3) == 't') ||(str.charAt(str.length() - 1) == 'g' && str.charAt(str.length() - 2) == 'o' &&str.charAt(str.length() - 3) == 'l')) {return 3;} else if((str.charAt(str.length() - 1) == 'n' && str.charAt(str.length() - 2) == 'l') ||(str.charAt(str.length() - 1) == '!' && str.charAt(str.length() - 2) == 'n')) {return 2;} else { return 1; }}  /** 检测函数,对str进行前后语法检测* 为Tip的提示方式提供依据,与TipShow()配合使用*  编号 字符    其后可以跟随的合法字符*   1  (                 数字|(|-|.|函数*   2   )                算符|)|√ ^*   3  .      数字|算符|)|√ ^*   4   数字        .|数字|算符|)|√ ^*   5   算符             数字|(|.|函数*   6 √ ^     ( |. | 数字*   7  函数           数字|(|.*   * 小数点前后均可省略,表示0* 数字第一位可以为0*/private void TipChecker(String tipcommand1,String tipcommand2) {//Tipcode1表示错误类型,Tipcode2表示名词解释类型int Tipcode1 = 0 , Tipcode2 = 0;//表示命令类型int tiptype1 = 0 , tiptype2 = 0;//括号数int bracket = 0;//“+-x÷√^”不能作为第一位if(tipcommand1.compareTo("#") == 0 && (tipcommand2.compareTo("÷") == 0 || tipcommand2.compareTo("×") == 0 || tipcommand2.compareTo("+") == 0 || tipcommand2.compareTo(")") == 0 || tipcommand2.compareTo("√") == 0 ||tipcommand2.compareTo("^") == 0)) {Tipcode1 = -1;}//定义存储字符串中最后一位的类型else if(tipcommand1.compareTo("#") != 0) {if(tipcommand1.compareTo("(") == 0) {tiptype1 = 1;} else if(tipcommand1.compareTo(")") == 0) {tiptype1 = 2;} else if(tipcommand1.compareTo(".") == 0) {tiptype1 = 3;} else if("0123456789".indexOf(tipcommand1) != -1) {tiptype1 = 4;} else if("+-×÷".indexOf(tipcommand1) != -1) {tiptype1 = 5;} else if("√^".indexOf(tipcommand1) != -1) {tiptype1 = 6;} else if("sincostanloglnn!".indexOf(tipcommand1) != -1) {tiptype1 = 7;}//定义欲输入的按键类型if(tipcommand2.compareTo("(") == 0) {tiptype2 = 1;} else if(tipcommand2.compareTo(")") == 0) {tiptype2 = 2;} else if(tipcommand2.compareTo(".") == 0) {tiptype2 = 3;} else if("0123456789".indexOf(tipcommand2) != -1) {tiptype2 = 4;} else if("+-×÷".indexOf(tipcommand2) != -1) {tiptype2 = 5;} else if("√^".indexOf(tipcommand2) != -1) {tiptype2 = 6;} else if("sincostanloglnn!".indexOf(tipcommand2) != -1) {tiptype2 = 7;}switch(tiptype1) {case 1://左括号后面直接接右括号,“+x÷”(负号“-”不算),或者"√^"if(tiptype2 == 2 || (tiptype2 == 5 && tipcommand2.compareTo("-") != 0) || tiptype2 == 6) Tipcode1 = 1;break;case 2://右括号后面接左括号,数字,“+-x÷sin^...”if(tiptype2 == 1 || tiptype2 == 3 || tiptype2 == 4 || tiptype2 == 7)Tipcode1 = 2;break;case 3://“.”后面接左括号或者“sincos...”if(tiptype2 == 1 || tiptype2 == 7)Tipcode1 = 3;//连续输入两个“.”if(tiptype2 == 3)Tipcode1 = 8;break;            case 4://数字后面直接接左括号或者“sincos...”if(tiptype2 == 1 || tiptype2 == 7)Tipcode1 = 4;break;case 5://“+-x÷”后面直接接右括号,“+-x÷√^”if(tiptype2 == 2 || tiptype2 == 5 || tiptype2 == 6)Tipcode1 = 5;break;case 6://“√^”后面直接接右括号,“+-x÷√^”以及“sincos...”if(tiptype2 == 2 || tiptype2 == 5 || tiptype2 == 6 || tiptype2 == 7)Tipcode1 = 6;break;case 7://“sincos...”后面直接接右括号“+-x÷√^”以及“sincos...”if(tiptype2 == 2 || tiptype2 == 5 || tiptype2 == 6 || tiptype2 == 7)Tipcode1 = 7;break;}}//检测小数点的重复性,Tipconde1=0,表明满足前面的规则if(Tipcode1 == 0 && tipcommand2.compareTo(".") == 0) {int tip_point = 0;for(int i = 0;i < tip_i;i++) {//若之前出现一个小数点点,则小数点计数加1if(Tipcommand[i].compareTo(".") == 0) {tip_point++;}//若出现以下几个运算符之一,小数点计数清零if(Tipcommand[i].compareTo("sin") == 0 || Tipcommand[i].compareTo("cos") == 0 ||Tipcommand[i].compareTo("tan") == 0 || Tipcommand[i].compareTo("log") == 0 ||Tipcommand[i].compareTo("ln") == 0 || Tipcommand[i].compareTo("n!") == 0 || Tipcommand[i].compareTo("√") == 0 || Tipcommand[i].compareTo("^") == 0 || Tipcommand[i].compareTo("÷") == 0 || Tipcommand[i].compareTo("×") == 0 || Tipcommand[i].compareTo("-") == 0 || Tipcommand[i].compareTo("+") == 0 || Tipcommand[i].compareTo("(") == 0 || Tipcommand[i].compareTo(")") == 0 ) {tip_point = 0;}}tip_point++;//若小数点计数大于1,表明小数点重复了if(tip_point > 1) {Tipcode1 = 8;}}//检测右括号是否匹配if(Tipcode1 == 0 && tipcommand2.compareTo(")") == 0) {int tip_right_bracket = 0;for(int i = 0;i < tip_i;i++) {//如果出现一个左括号,则计数加1if(Tipcommand[i].compareTo("(") == 0) {tip_right_bracket++;}//如果出现一个右括号,则计数减1if(Tipcommand[i].compareTo(")") == 0) {tip_right_bracket--;}}//如果右括号计数=0,表明没有响应的左括号与当前右括号匹配if(tip_right_bracket == 0) {Tipcode1 = 10; }}//检查输入=的合法性if(Tipcode1 == 0 && tipcommand2.compareTo("=") == 0) {//括号匹配数int tip_bracket = 0; for(int i = 0;i < tip_i;i++) {if(Tipcommand[i].compareTo("(") == 0) {tip_bracket++;}if(Tipcommand[i].compareTo(")") == 0) {tip_bracket--;}}//若大于0,表明左括号还有未匹配的if(tip_bracket > 0) {Tipcode1 = 9; bracket = tip_bracket;} else if(tip_bracket == 0) {//若前一个字符是以下之一,表明=号不合法if("√^sincostanloglnn!".indexOf(tipcommand1) != -1) {Tipcode1 = 6;}//若前一个字符是以下之一,表明=号不合法if("+-×÷".indexOf(tipcommand1) != -1) {Tipcode1 = 5;}}}//若命令式以下之一,则显示相应的帮助信息if(tipcommand2.compareTo("MC") == 0) Tipcode2 = 1;if(tipcommand2.compareTo("C") == 0) Tipcode2 = 2;if(tipcommand2.compareTo("DRG") == 0) Tipcode2 = 3;if(tipcommand2.compareTo("Bksp") == 0) Tipcode2 = 4;if(tipcommand2.compareTo("sin") == 0) Tipcode2 = 5;if(tipcommand2.compareTo("cos") == 0) Tipcode2 = 6;if(tipcommand2.compareTo("tan") == 0) Tipcode2 = 7;if(tipcommand2.compareTo("log") ==0) Tipcode2 = 8;if(tipcommand2.compareTo("ln") == 0) Tipcode2 = 9;if(tipcommand2.compareTo("n!") == 0) Tipcode2 = 10;if(tipcommand2.compareTo("√") == 0) Tipcode2 = 11;if(tipcommand2.compareTo("^") == 0) Tipcode2 = 12;//显示帮助和错误信息TipShow(bracket , Tipcode1 , Tipcode2 , tipcommand1 , tipcommand2);}/** 反馈Tip信息,加强人机交互,与TipChecker()配合使用*/private void TipShow(int bracket , int tipcode1 , int tipcode2 , String tipcommand1 , String tipcommand2) {String tipmessage = "";if(tipcode1 != 0) tip_lock = false;//表明输入有误switch(tipcode1) {case -1:tipmessage = tipcommand2 + "  不能作为第一个算符\n";break;case 1:tipmessage = tipcommand1 + "  后应输入:数字/(/./-/函数 \n";break;case 2:tipmessage = tipcommand1 + "  后应输入:)/算符 \n";break;case 3:tipmessage = tipcommand1 + "  后应输入:)/数字/算符 \n";break;case 4:tipmessage = tipcommand1 + "  后应输入:)/./数字 /算符 \n";break;case 5:tipmessage = tipcommand1 + "  后应输入:(/./数字/函数 \n";break;case 6:tipmessage = tipcommand1 + "  后应输入:(/./数字 \n";break;case 7:tipmessage = tipcommand1 + "  后应输入:(/./数字 \n";break;case 8:tipmessage = "小数点重复\n";break;case 9:tipmessage = "不能计算,缺少 "+ bracket +" 个 )";break;case 10:tipmessage = "不需要  )";break;}        switch(tipcode2) {case 1:tipmessage = tipmessage + "[MC 用法: 清除记忆 MEM]";break;case 2:tipmessage = tipmessage + "[C 用法: 归零]";break;case 3:tipmessage = tipmessage + "[DRG 用法: 选择 DEG 或 RAD]";break;case 4:tipmessage = tipmessage + "[Bksp 用法: 退格]";break;case 5:tipmessage = tipmessage + "sin 函数用法示例:\n" +"DEG:sin30 = 0.5      RAD:sin1 = 0.84\n" +"注:与其他函数一起使用时要加括号,如:\n" +"sin(cos45),而不是sincos45" ;break;case 6:tipmessage = tipmessage + "cos 函数用法示例:\n" +"DEG:cos60 = 0.5      RAD:cos1 = 0.54\n" +"注:与其他函数一起使用时要加括号,如:\n" +"cos(sin45),而不是cossin45" ;break;case 7:tipmessage = tipmessage + "tan 函数用法示例:\n" +"DEG:tan45 = 1      RAD:tan1 = 1.55\n" +"注:与其他函数一起使用时要加括号,如:\n" +"tan(cos45),而不是tancos45" ;break;case 8:tipmessage = tipmessage + "log 函数用法示例:\n" +"log10 = log(5+5) = 1\n" +"注:与其他函数一起使用时要加括号,如:\n" +"log(tan45),而不是logtan45" ;break;case 9:tipmessage = tipmessage + "ln 函数用法示例:\n" +"ln10 = le(5+5) = 2.3   lne = 1\n" +"注:与其他函数一起使用时要加括号,如:\n" +"ln(tan45),而不是lntan45" ;break;case 10:tipmessage = tipmessage + "n! 函数用法示例:\n" +"n!3 = n!(1+2) = 3×2×1 = 6\n" +"注:与其他函数一起使用时要加括号,如:\n" +"n!(log1000),而不是n!log1000" ;break;case 11:tipmessage = tipmessage + "√ 用法示例:开任意次根号\n" +"如:27开3次根为  27√3 = 3\n" +"注:与其他函数一起使用时要加括号,如:\n" +"(函数)√(函数) , (n!3)√(log100) = 2.45";break;case 12:tipmessage = tipmessage + "^ 用法示例:开任意次平方\n" +"如:2的3次方为  2^3 = 8\n" +"注:与其他函数一起使用时要加括号,如:\n" +"(函数)√(函数) , (n!3)^(log100) = 36";break;}//将提示信息显示到tiptip.setText(tipmessage);}/** 整个计算核心,只要将表达式的整个字符串传入calc().process()就可以实行计算了* 算法包括以下几部分:* 1、计算部分           process(String str)  当然,这是建立在查错无错误的情况下* 2、数据格式化      FP(double n)         使数据有相当的精确度* 3、阶乘算法           N(double n)          计算n!,将结果返回* 4、错误提示          showError(int code ,String str)  将错误返回*/public class calc {public calc(){}final int MAXLEN = 500;/* * 计算表达式* 从左向右扫描,数字入number栈,运算符入operator栈* +-基本优先级为1,×÷基本优先级为2,log ln sin cos tan n!基本优先级为3,√^基本优先级为4* 括号内层运算符比外层同级运算符优先级高4* 当前运算符优先级高于栈顶压栈,低于栈顶弹出一个运算符与两个数进行运算* 重复直到当前运算符大于栈顶* 扫描完后对剩下的运算符与数字依次计算*/public void process(String str) {int weightPlus = 0, topOp = 0,topNum = 0, flag = 1, weightTemp = 0;//weightPlus为同一()下的基本优先级,weightTemp临时记录优先级的变化//topOp为weight[],operator[]的计数器;topNum为number[]的计数器//flag为正负数的计数器,1为正数,-1为负数int weight[];  //保存operator栈中运算符的优先级,以topOp计数double number[];  //保存数字,以topNum计数char ch, ch_gai, operator[];//operator[]保存运算符,以topOp计数String num;//记录数字,str以+-×÷()sctgl!√^分段,+-×÷()sctgl!√^字符之间的字符串即为数字weight = new int[MAXLEN];number = new double[MAXLEN];operator = new char[MAXLEN];String expression = str;StringTokenizer expToken = new StringTokenizer(expression,"+-×÷()sctgl!√^");int i = 0;while (i < expression.length()) {ch = expression.charAt(i);//判断正负数if (i == 0) {if (ch == '-')flag = -1;} else if(expression.charAt(i-1) == '(' && ch == '-')flag = -1;//取得数字,并将正负符号转移给数字if (ch <= '9' && ch >= '0'|| ch == '.' || ch == 'E') {num = expToken.nextToken();ch_gai = ch;Log.e("guojs",ch+"--->"+i);//取得整个数字while (i < expression.length() && (ch_gai <= '9' && ch_gai >= '0'|| ch_gai == '.' || ch_gai == 'E')) {ch_gai = expression.charAt(i++);Log.e("guojs","i的值为:"+i);}//将指针退回之前的位置if (i >= expression.length()) i-=1; else {i-=2;}if (num.compareTo(".") == 0) number[topNum++] = 0;//将正负符号转移给数字else {number[topNum++] = Double.parseDouble(num)*flag;flag = 1;}}//计算运算符的优先级if (ch == '(') weightPlus+=4;if (ch == ')') weightPlus-=4;if (ch == '-' && flag == 1 || ch == '+' || ch == '×'|| ch == '÷' || ch == 's' ||ch == 'c' || ch == 't' || ch == 'g' || ch == 'l' || ch == '!' || ch == '√' || ch == '^') {switch (ch) {//+-的优先级最低,为1case '+':case '-':weightTemp = 1 + weightPlus;break;//x÷的优先级稍高,为2case '×':case '÷':weightTemp = 2 + weightPlus;break;//sincos之类优先级为3case 's':case 'c':case 't':case 'g':case 'l':case '!':weightTemp = 3 + weightPlus;break;//其余优先级为4//case '^'://case '√':default:weightTemp = 4 + weightPlus;break;}//如果当前优先级大于堆栈顶部元素,则直接入栈if (topOp == 0 || weight[topOp-1] < weightTemp) {weight[topOp] = weightTemp;operator[topOp] = ch;topOp++;//否则将堆栈中运算符逐个取出,直到当前堆栈顶部运算符的优先级小于当前运算符}else {while (topOp > 0 && weight[topOp-1] >= weightTemp) {switch (operator[topOp-1]) {//取出数字数组的相应元素进行运算case '+':number[topNum-2]+=number[topNum-1];break;case '-':number[topNum-2]-=number[topNum-1];break;case '×':number[topNum-2]*=number[topNum-1];break;//判断除数为0的情况case '÷':if (number[topNum-1] == 0) {showError(1,str_old);return;}number[topNum-2]/=number[topNum-1];break;case '√':if(number[topNum-1] == 0 || (number[topNum-2] < 0 &&number[topNum-1] % 2 == 0)) {showError(2,str_old);return;    } number[topNum-2] = Math.pow(number[topNum-2], 1/number[topNum-1]);break;case '^':number[topNum-2] = Math.pow(number[topNum-2], number[topNum-1]);break;//计算时进行角度弧度的判断及转换//sincase 's':if(drg_flag == true) {number[topNum-1] = Math.sin((number[topNum-1]/180)*pi);} else {number[topNum-1] = Math.sin(number[topNum-1]);}topNum++;break;//coscase 'c':if(drg_flag == true) {number[topNum-1] = Math.cos((number[topNum-1]/180)*pi);} else {number[topNum-1] = Math.cos(number[topNum-1]);}topNum++;break;//tancase 't':if(drg_flag == true) {if((Math.abs(number[topNum-1])/90)%2 == 1) {showError(2,str_old);return;}number[topNum-1] = Math.tan((number[topNum-1]/180)*pi);} else {if((Math.abs(number[topNum-1])/(pi/2))%2 == 1) {showError(2,str_old);return;}number[topNum-1] = Math.tan(number[topNum-1]);}topNum++;break;//logcase 'g':if(number[topNum-1] <= 0) {showError(2,str_old);return;    } number[topNum-1] = Math.log10(number[topNum-1]);topNum++;break;//lncase 'l':if(number[topNum-1] <= 0) {showError(2,str_old);return;    } number[topNum-1] = Math.log(number[topNum-1]);topNum++;break;//阶乘case '!':if(number[topNum-1] > 170) {showError(3,str_old);return;    } else if(number[topNum-1] < 0) {showError(2,str_old);return;}number[topNum-1] = N(number[topNum-1]);topNum++;break;}//继续取堆栈的下一个元素进行判断topNum--;topOp--;}//将运算符如堆栈weight[topOp] = weightTemp;operator[topOp] = ch;topOp++;}}i++;}//依次取出堆栈的运算符进行运算while (topOp>0) {//+-x直接将数组的后两位数取出运算switch (operator[topOp-1]) {case '+':number[topNum-2]+=number[topNum-1];break;case '-':number[topNum-2]-=number[topNum-1];break;case '×':number[topNum-2]*=number[topNum-1];break;//涉及到除法时要考虑除数不能为零的情况case '÷':if (number[topNum-1] == 0) {showError(1,str_old);return;}number[topNum-2]/=number[topNum-1];break;case '√':if(number[topNum-1] == 0 || (number[topNum-2] < 0 &&number[topNum-1] % 2 == 0)) {showError(2,str_old);return;    } number[topNum-2] = Math.pow(number[topNum-2], 1/number[topNum-1]);break;case '^':number[topNum-2] = Math.pow(number[topNum-2], number[topNum-1]);break;//sincase 's':if(drg_flag == true) {number[topNum-1] = Math.sin((number[topNum-1]/180)*pi);} else {number[topNum-1] = Math.sin(number[topNum-1]);}topNum++;break;//coscase 'c':if(drg_flag == true) {number[topNum-1] = Math.cos((number[topNum-1]/180)*pi);} else {number[topNum-1] = Math.cos(number[topNum-1]);}topNum++;break;//tancase 't':if(drg_flag == true) {if((Math.abs(number[topNum-1])/90)%2 == 1) {showError(2,str_old);return;}number[topNum-1] = Math.tan((number[topNum-1]/180)*pi);} else {if((Math.abs(number[topNum-1])/(pi/2))%2 == 1) {showError(2,str_old);return;}number[topNum-1] = Math.tan(number[topNum-1]);}topNum++;break;//对数logcase 'g':if(number[topNum-1] <= 0) {showError(2,str_old);return;    } number[topNum-1] = Math.log10(number[topNum-1]);topNum++;break;//自然对数lncase 'l':if(number[topNum-1] <= 0) {showError(2,str_old);return;    } number[topNum-1] = Math.log(number[topNum-1]);topNum++;break;//阶乘case '!':if(number[topNum-1] > 170) {showError(3,str_old);return;    } else if(number[topNum-1] < 0) {showError(2,str_old);return;}number[topNum-1] = N(number[topNum-1]);topNum++;break;}//取堆栈下一个元素计算topNum--;topOp--;}//如果是数字太大,提示错误信息if(number[0] > 7.3E306) {showError(3,str_old);return;}//输出最终结果input.setText(String.valueOf(FP(number[0]))); tip.setText("计算完毕,要继续请按归零键 C");mem.setText(str_old+"="+String.valueOf(FP(number[0])));}/** FP = floating point 控制小数位数,达到精度* 否则会出现 0.6-0.2=0.39999999999999997的情况,用FP即可解决,使得数为0.4* 本格式精度为15位*/public double FP(double n) {//NumberFormat format=NumberFormat.getInstance();  //创建一个格式化类f//format.setMaximumFractionDigits(18);    //设置小数位的格式DecimalFormat format = new DecimalFormat("0.#############");return Double.parseDouble(format.format(n));}/** 阶乘算法*/public double N(double n) { int i = 0;double sum = 1;//依次将小于等于n的值相乘for(i = 1;i <= n;i++) {sum = sum*i;}return sum;}/** 错误提示,按了"="之后,若计算式在process()过程中,出现错误,则进行提示*/public void showError(int code ,String str) {String message="";switch (code) {case 1:message = "零不能作除数";break;case 2:message = "函数格式错误";break;case 3:message = "值太大了,超出范围";}input.setText("\""+str+"\""+": "+message);tip.setText(message+"\n"+"计算完毕,要继续请按归零键 C");}  }
}

Android高级计算器相关推荐

  1. android高级编程-android高级应用

    android高级应用>>> 第一阶段 程序员基本素质养成 程序员所需要具备的12条职业素质 让学员初步了解和审视自己所应该具备的职业素质.并且我们会在授课中随时训练和贯彻这样的素质 ...

  2. 如何学习android高级编程

    学了android高级编程有前途吗?进入2010年之后,android的应用开发进入了一个爆炸式增长的状态,从去年的不到1万款应用程序增加到现在的9万,而且即将突破10万,这也从开发者这一方面展现了用 ...

  3. Android高级大纲

    2019独角兽企业重金招聘Python工程师标准>>> 1.Android高级UI开发 Android高级UI开发.png 2.Android性能优化 Android性能优化.png ...

  4. 耗时118天爆肝【1296页】的“Android高级开发面试题”,终于成功上岸字节

    前言 本人16年毕业于一家普通二本,考研裂开了且没有实习经验,只做过两个项目,每天就是不断地投简历.刷面经,感觉自己都要抑郁了,最后勉强进入了一家学校合作的互联网公司,后面陆陆续续也换了几家公司,毕业 ...

  5. Android高级第九讲--JVM 与Android Dalvik之间的异同

    博客出自:http://blog.csdn.net/liuxian13183,转载注明出处! All Rights Reserved ! 有些东西不是不知道,是还没用到,所以才没去仔细了解,昨天被问及 ...

  6. android炫酷动画代码,Android高级UI特效仿直播点赞动画效果

    Android高级UI特效仿直播点赞动画效果 发布时间:2020-10-02 16:06:18 来源:脚本之家 阅读:117 作者:mrr 本文给大家分享高级UI特效仿直播点赞效果-一个优美炫酷的点赞 ...

  7. Android高级开发专题晋升班

    Android高级开发专题晋升班 适用人群:1-3年以上经验的开发者丨学员平均薪酬20K/月 转载于:https://www.cnblogs.com/lythonliu/p/6285531.html

  8. 这些Android高级必会知识点你能答出来几个?含BATJM大厂

    前言 首先介绍一下自己,计算机水本,考研与我无缘.之前在帝都某公司算法部实习,公司算大公司吧,然而个人爱好偏开发,大二的时候写个一个app,主要是用各种框架. 一.掌握架构师筑基必备技能 二.掌握An ...

  9. android高级资料

    自己写一个组件化的工程: https://juejin.im/post/5cc5b3055188255e341c42ba android把一个module打包成maven仓库,arr文件,远程访问其中 ...

  10. android 移除泛型中元素_最新(2020)Android高级面试知识点干货分享(二)

    最新Android高级面试知识点干货分享(一) *转载请说明出处*! 四.Java集合(List.Set.Queue.Map) Java集合体系是一个树状,如果按照类似OSI网络模型来看的话,整个Ja ...

最新文章

  1. JavaScript权威指南--window对象
  2. 【脚本整理】docker-compose 部署prometheus + grafana
  3. CentOs7 无可用“Chinese Support“
  4. 世界上第一台现代计算机是什么
  5. Python3之logging输出写入日志
  6. 4. Spring Boot 过滤器、监听器
  7. python学习笔记之读取配置文件【转自https://my.oschina.net/u/3041656/blog/793467】
  8. AODV的设计思路和现有的各种解决方案的优缺点
  9. 题解:100元买100只鸡,公鸡4元一只,母鸡3元一只,小鸡1元3只,问公鸡,母鸡,小鸡各买了多少只?
  10. 你的工作表现是否成熟,用这4条检验自己
  11. vue入门之04-生命周期 数据共享
  12. LQ0266 巧排扑克牌【模拟】
  13. 如何将一个软件添加到鼠标右键
  14. 英:程序员 外企 英语常用语 (整理)
  15. MOS管的工作原理和区分
  16. Ubuntu 16.04安装tomcat8
  17. 各大公司的java面试题库
  18. python爬虫壁纸网站(有源码)
  19. 使用FloatingActionButton滑动消失后不再显示
  20. iso20000认证一般要多少费用

热门文章

  1. freeSSL申请证书加阿里云域名解析加nginx配置
  2. python制作动态时钟_python实现简易动态时钟
  3. 美团工作10个月心得
  4. Linux XFS 文件系统文件的删除恢复
  5. mapbox/minemap 首屏固定比例尺为1:20
  6. date类型被fastjson变为long类型一串数字
  7. 光学三原色与色的三原色
  8. 【淘宝0元购】,所有人无门槛参与!
  9. html简单登录页面代码
  10. 图片如何无损放大?图片放大不失真的神器