一、应用介绍

安卓计算器:
实现功能:
(1)能实现基本的加减乘除运算、回退和清空输入。
(2)竖屏时能实现基本的加减乘除运算、回退和清空输入。横屏时变为科学计算器,实现函数计算、进制换算等功能。
(3)数字按键依照电话拨号键盘顺序排列。
(4)点击菜单可对计算器相关特性进行配置。
(5)输入计算公式,按等号键输出计算结果。
(6)公式输入和结果显示区应支持长按弹出复制、粘贴功能。
(7)使用计算器过程中应不弹出软键盘。
(8)可以通过进度条实时调整计算结果保留的小数点后位数,或者通过音量键完成同样的效果。
(9)实现附加功能:三角函数、阶乘、XY、√(Y&X)及括号,如sin(90)。
(10)输入表达式按优先级计算,按等号输出结果。
(11)对常用键布局需考虑特殊处理。
(12)处理精度和容错问题:
a.1/3+1/3+1/3;
2.1+0.001;
1.1-1.001;
1/0、1/(1-1)和1/sin(0)等;
3/2;
对有附加功能的需要处理特殊值,如:√(2&-1) 等。

二、 运行截图

竖屏时


横屏时

主要代码
MainActivity.java

public class MainActivity extends AppCompatActivity {String formula = "";//公式方程Boolean zeroMark = true; //允许输入一个0Boolean zeroCon = false;//允许持续输入0Boolean docMark = true;// . 可以输入 .Boolean resultMark = false; //结果是否计算出Boolean transformMark = false; //是否进行二进制转化Boolean errorMark = false;Boolean numAndOpMark = true;int color = 0xffffffff;private static final String REGEX = "^\\d+$";//all is numint precision = 3; //保留小数点位数@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR); //屏幕旋转setContentView(R.layout.col);EditText show = findViewById(R.id.show);show.setText("");show.setSelectAllOnFocus(true);  // 设置长按时选择全部calculator();}public void calculator() {disableShowInput(); // 不让弹出软键盘EditText show = findViewById(R.id.show);Button dot = findViewById(R.id.dot);Button zero = findViewById(R.id.zero);Button one = findViewById(R.id.one);Button two = findViewById(R.id.two);Button three = findViewById(R.id.three);Button four = findViewById(R.id.four);Button five = findViewById(R.id.five);Button six = findViewById(R.id.six);Button seven = findViewById(R.id.seven);Button eight = findViewById(R.id.eight);Button nine = findViewById(R.id.nine);Button add = findViewById(R.id.add);Button sub = findViewById(R.id.sub);Button division = findViewById(R.id.division);Button back = findViewById(R.id.back);Button AC = findViewById(R.id.AC);Button mul = findViewById(R.id.mul);Button eval = findViewById(R.id.eval);Button percent = findViewById(R.id.percent);Button sin = findViewById(R.id.sin);Button power = findViewById(R.id.power);Button factorial = findViewById(R.id.factorial); //阶乘Button square = findViewById(R.id.square); //开根号Button brackets = findViewById(R.id.brackets);Button transform = findViewById(R.id.transform);dot.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum(".");}});zero.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("0");}});one.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("1");}});two.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("2");}});three.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("3");}});four.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("4");}});five.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("5");}});six.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("6");}});seven.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("7");}});eight.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("8");}});nine.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("9");}});add.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doOp("+");}});sub.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doOp("-");}});mul.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doOp("×");}});division.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doOp("÷");}});AC.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {reSetStatus();show.setText("");}});back.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (formula.length() > 0) {if (!formula.contains("(D->B)")) {if (lastStr().equals(".")) {docMark = true;}formula = formula.substring(0, formula.length() - 1);} else {formula = formula.replace("(D->B)", "");numAndOpMark = true;transformMark = false;}show.setText(formula);show.setTextColor(0xff000000);}}});eval.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {try {String result = "";if (transformMark) {  // 先判断是不是要进行二进制转化doTransform();return;}delLastOp(); // 如果式子是 4- 进行计算,我们打算将-号去掉,结果为4try {result = Result.getRes(formula) + ""; //将计算式放入getRes函数中进行计算} catch (Exception e) {show.setText(e.getMessage()); //getRes中抛出的异常进行抓取并显示show.setTextColor(0xffff0000);errorMark = true;return;}System.out.println(result + "result");if (result.contains("E") && !result.contains("E-")) {// 结果使用了科学计数法表示,我们要根据情况进行处理show.setText(result);Toast toast = Toast.makeText(getApplicationContext(), "数值太大,已用科学计数法表示", Toast.LENGTH_SHORT);toast.show();return;}
//                    String intPart;//              if (result.length() > 12) {if (result.contains("E-")) {BigDecimal decimal = new BigDecimal(result);result = decimal.toPlainString();}if (result.length() > 12){result = result.substring(0, 11);}result = doPrecision(result);  //进行精读修改show.setText(result);reSetStatus();formula = result;resultMark = true;docMark = true;} catch (Exception e) {e.printStackTrace();}}});percent.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (formula.length() > 0) {if (!numAndOpMark) {return;}formula = "(" + formula + ")*0.01";try {show.setText(doEval(formula));formula = doEval(formula);} catch (Exception e) {show.setText(e.getMessage());}}}});sin.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (!numAndOpMark) {return;}formula = formula + "sin(";show.setText(formula);}});square.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (!numAndOpMark) {return;}formula = formula + "v(";show.setText(formula);}});power.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (!numAndOpMark) {return;}formula = formula + "^";show.setText(formula);}});factorial.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (!numAndOpMark) {return;}try {if (formula.contains(".") ){Toast toast = Toast.makeText(getApplicationContext(), "小数不可以阶乘", Toast.LENGTH_SHORT);toast.show();return;}if (Result.getRes(formula) < 171) {formula = formula + "!";show.setText(formula);} else {Toast toast = Toast.makeText(getApplicationContext(), "数值太大!", Toast.LENGTH_SHORT);toast.show();show.setTextColor(0xffff0000);resultMark = true;}} catch (Exception e) {e.printStackTrace();}}});brackets.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (!numAndOpMark) {return;}if (lastIsNum() || lastStr().equals(")")) {formula = formula + ")";} else {formula = formula + "(";}show.setText(formula);}});transform.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (formula.matches(REGEX)) {formula = formula + "(D->B)";show.setText(formula);transformMark = true;numAndOpMark = false;}}});}public String doPrecision(String result) {System.out.println(result + "rep");String tail = result.split("\\.")[1];String pre = result.split("\\.")[0];int deltaPre = precision - tail.length();if (deltaPre > 0) {for (int i = 0; i < deltaPre; i++) {result = result + "0";}} else if (deltaPre < 0) {double doubleResult = Double.parseDouble(result);BigDecimal bigResult = new BigDecimal(doubleResult);result = bigResult.setScale(precision, BigDecimal.ROUND_HALF_UP).toString();}System.out.println(result + "pre");return result;}public void reSetStatus() {  //将各个监控状态设为初始状态EditText show = findViewById(R.id.show);show.setTextColor(0xff000000);formula = "";zeroMark = true;zeroCon = false;docMark = true;resultMark = false;transformMark = false;numAndOpMark = true;}@SuppressLint("SetTextI18n")public void doTransform() {  //二进制转化方法EditText show = findViewById(R.id.show);transformMark = false;String num = formula.split("\\(")[0];show.setText(Integer.toBinaryString(Integer.parseInt(num)) + "B");resultMark = true;docMark = true;}public String lastStr() {if (formula.length() > 0) {return formula.charAt(formula.length() - 1) + "";} else {return "";}}  //返回字符的最后一个字符public String doEval(String formula) throws Exception {  //做简单的计算方法ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine se = manager.getEngineByName("js");return se.eval(formula) + "";}public Boolean lastIsNum() {  //最后一位是不是数字if (formula.length() == 0) {return false;} else {char lastChar = formula.charAt(formula.length() - 1);return lastChar > 47 && lastChar < 58;}}public Boolean lastIsOp() {  //最后一位字符是不是操作符return isOp(lastStr());}public Boolean isOp(String str) {  //传递的参数是不是操作符return (str.equals("+") || str.equals("×")|| str.equals("÷") || str.equals("-"));}public void doNum(String num) {EditText show = findViewById(R.id.show);show.setTextColor(0xff000000);int length = formula.length();if (!numAndOpMark) {  //当使用(D->B)后我们不再允许进行任何符号的输入return;}if (errorMark) {  //是否出错reSetStatus();errorMark = false;}if (resultMark) { //结果是否已算出formula = "";resultMark = false;}if (num.equals(".")) {  //输的字符是不是点   .000000000000if (docMark) { // && !isOp(lastStr())formula = formula + '.';show.setText(formula);docMark = false;zeroCon = true;}return;}if (num.equals("0")) {  //是不是0?   00000000000if (zeroCon || zeroMark) {formula = formula + '0';}show.setText(formula);zeroMark = false;return;}if (formula.startsWith("0") && length == 1) {  //0的特殊情况   09 -> 9formula = "";}if (length > 2 && formula.endsWith("0") && isOp(formula.charAt(length - 2) + "")) {formula = formula.substring(0, length - 1); // 0的特殊情况  23 + 09  -> 23 + 9}formula = formula + num;  //加入计算式zeroCon = true;show.setText(formula);}public void doOp(String op) {EditText show = findViewById(R.id.show);show.setTextColor(0xff000000);if (!numAndOpMark || lastStr().equals(".")) {return;}if (errorMark) {  //是否有错误  - is okreSetStatus();errorMark = false;}if (resultMark) { //结果是否计算出formula = show.getText().toString();resultMark = false;}if ((lastStr().equals("÷") || lastStr().equals("×")) && op.equals("-")) {addOp(op);return;}if (formula.contains("×-") || formula.contains("÷-")) {formula = formula.substring(0, formula.length() - 2);}if (formula.length() == 1 && lastStr().equals("-")) {  // 只有一个减号,不允许输任何操作符return;}if (formula.length() == 0 || lastStr().equals("(")) {  //1+(?=-if (op.equals("-")) { // 第一个输入的字符是不是-addOp(op);}return;}if (lastIsOp() && formula.length() > 0) {  //若最后一个字符已经时操作符,那要替换掉旧的替换符formula = formula.substring(0, formula.length() - 1);}addOp(op);  //如果没有以上特殊情况,则加到计算式里}public void addOp(String op) { // 输入操作符时大部分的重复工作进行封装EditText show = findViewById(R.id.show);formula = formula + op;docMark = true;zeroMark = true;zeroCon = false;show.setText(formula);}//==================================================================================@SuppressLint("SetTextI18n")@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {  //设置精度(通过音量键)TextView info = findViewById(R.id.info);switch (keyCode) {case KeyEvent.KEYCODE_VOLUME_DOWN:if (precision > 1) {precision--;info.setText("保留" + precision + "位");Toast.makeText(this, "保留" + precision + "位", Toast.LENGTH_SHORT).show();} else {Toast.makeText(this, "至少保留1位", Toast.LENGTH_SHORT).show();}break;case KeyEvent.KEYCODE_VOLUME_UP:if (precision < 10) {precision++;Toast.makeText(this, "保留" + precision + "位", Toast.LENGTH_SHORT).show();info.setText("保留" + precision + "位");} else {Toast.makeText(this, "至多保留10位", Toast.LENGTH_SHORT).show();}break;}return super.onKeyDown(keyCode, event);}@SuppressLint("SetTextI18n")@Overridepublic void onConfigurationChanged(Configuration newConfig) {  //横竖屏切换时进行设置@SuppressLint("CutPasteId") EditText show1 = findViewById(R.id.show);color = show1.getCurrentTextColor();formula = show1.getText().toString(); //如果你是复制进去的式子,那必须先从show中得到式子// TODO Auto-generated method stubsuper.onConfigurationChanged(newConfig);//启动时默认是竖屏if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {setContentView(R.layout.col);@SuppressLint("CutPasteId") EditText show = findViewById(R.id.show);show.setText(formula);show.setTextColor(color);calculator();}//切换就是横屏else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {setContentView(R.layout.row);@SuppressLint("CutPasteId") EditText show = findViewById(R.id.show);TextView info = findViewById(R.id.info);info.setText("保留" + precision + "位");show.setText(formula);show.setTextColor(color);calculator();}}//========================================================================================@Overridepublic boolean onCreateOptionsMenu(Menu menu) {  //生成菜单项MenuInflater inflater = new MenuInflater(this);inflater.inflate(R.menu.menu, menu);return super.onCreateOptionsMenu(menu);}@SuppressLint("NonConstantResourceId")@Override  //菜单项无所谓public boolean onOptionsItemSelected(MenuItem item) {EditText show = findViewById(R.id.show);//先判断点击的是哪个idswitch (item.getItemId()) {case R.id.font_10:show.setTextSize(10 * 2);break;case R.id.font_12:show.setTextSize(12 * 2);break;case R.id.font_14:show.setTextSize(14 * 2);break;case R.id.font_16:show.setTextSize(16 * 2);break;case R.id.font_18:show.setTextSize(18 * 2);break;case R.id.blue:show.setTextColor(Color.BLUE);break;case R.id.red:show.setTextColor(Color.RED);break;case R.id.green:show.setTextColor(Color.GREEN);break;}return super.onOptionsItemSelected(item);}//======================================================================================public void disableShowInput() {  //设置键盘不可见EditText show = findViewById(R.id.show);Class<EditText> cls = EditText.class;Method method;try {method = cls.getMethod("setShowSoftInputOnFocus", boolean.class);method.setAccessible(true);method.invoke(show, false);} catch (Exception e) {//TODO: handle exception}try {method = cls.getMethod("setSoftInputShownOnFocus", boolean.class);method.setAccessible(true);method.invoke(show, false);} catch (Exception e) {//TODO: handle exception}}//=============================================================================public void delLastOp() {  //写个小递归,后来想想好像用不到,但懒得改了if (isOp(formula.charAt(formula.length() - 1) + "") || lastStr().equals(".")) {formula = formula.substring(0, formula.length() - 1);delLastOp();}}

ArrayStack.java


class ArrayStack {private int maxSize; // 栈的大小private double[] stack; // 数组,数组模拟栈,数据就放在该数组private int top = -1;// top表示栈顶,初始化为-1//构造器public ArrayStack(int maxSize) {this.maxSize = maxSize;stack = new double[this.maxSize];}//增加一个方法,可以返回当前栈顶的值, 但是不是真正的poppublic double peek() {return stack[top];}//栈满public boolean isFull() {return top == maxSize - 1;}//栈空public boolean isEmpty() {return top == -1;}//入栈-pushpublic void push(double value) {//先判断栈是否满if (isFull()) {System.out.println("表达式错误");return;}top++;stack[top] = value;}//出栈-pop, 将栈顶的数据返回public double pop() {//先判断栈是否空if (isEmpty()) {//抛出异常throw new RuntimeException("表达式错误");}double value = stack[top];top--;return value;}//显示栈的情况[遍历栈], 遍历时,需要从栈顶开始显示数据public void list() {if (isEmpty()) {System.out.println("表达式错误");return;}//需要从栈顶开始显示数据for (int i = top; i >= 0; i--) {System.out.printf("stack[%d]=%d\n", i, stack[i]);}}//返回运算符的优先级,优先级是程序员来确定, 优先级使用数字表示//数字越大,则优先级就越高.public int priority(int oper) {if (oper == '*' || oper == '/') {return 1;} else if (oper == '+' || oper == '-') {return 0;} else if (oper == '^'||oper == '#') {return 2;} else if (oper == '!' || oper == 'v' || oper == '%') {return 3;} else if (oper == 's' || oper == 't' || oper == 'c') {return 4;} else {return -1; // 假定目前的表达式只有 +, - , * , /}}//判断是不是一个运算符public boolean isNum(char val) {return '0' <= val && val <= '9';}//判断是不是一个运算符public boolean isOper(char val) {return val == '+' || val == '-' || val == '*' || val == '/' || val == '#' || val == '^' || val == '%' || val == 's' || val == 'c' || val == 't' || val == '!' || val == 'v';}//判断是不是 (public boolean isLeftBrackets(char val) {return val == '(';}//判断是不是 )public boolean isRightBrackets(char val) {return val == ')';}//判断是不是 .public boolean isPoint(char val) {return val == '.';}//判断是不是 (public boolean isTrigonometric(char val) {return val == 's';}//计算方法public double cal(double num1, double num2, int oper) {double res = 0; // res 用于存放计算的结果switch (oper) {case '+':res = num1 + num2;break;case '-':res = sub(num2,num1);// 注意顺序break;case '*':res = num1 * num2;break;case '/':if (num1 == 0) {throw new RuntimeException("定义域错误");}res = num2 / num1;break;case '^':res = Math.pow(num2, num1);break;default:break;}return res;}/*** 三角函数运算、阶乘运算或者是开根操作** @param num1* @param oper* @return*/public double mixedOperation(double num1, int oper) {double res = 1; // res 用于存放计算的结果switch (oper) {case 's':res = Math.sin(num1 * Math.PI / 180);break;case 'c':res = Math.cos(num1 * Math.PI / 180);break;case 't':res = Math.tan(num1 * Math.PI / 180);break;case '!':for (int i = 1; i <= num1; i++) {res *= i;}break;case 'v':if (num1 < 0) {throw new RuntimeException("定义域错误");}res = Math.sqrt(num1);break;case '%':res = num1 / 100;break;case '#':res = -num1;break;default:break;}return res;}double sub(double x, double y) {BigDecimal initResult = new BigDecimal(x - y);   //计算初步结果String temp = initResult.toString();if (temp.contains(".")){temp = temp + "00000000000000000000";}else {temp = temp + ".00000000000000000000";}int lengthOfInt = getLengthOfInt(x, y);   //结果整形位数int lengthOfDec = Math.max(getLengthOfDecimal(x), getLengthOfDecimal(y));int count = lengthOfInt + lengthOfDec + 2;  //最后输出的位数 = 整形位数+小数位数+小数点位数+1(四舍五入舍去)double tempResult = Double.parseDouble(temp.substring(0, count)); //将String转换成double,并截取多一位用于四舍五入double power = Math.pow(10, lengthOfDec);  //求10的几次方用来四舍五入double finalResult = (double) (Math.round(tempResult * power)) / power;  //四舍五入Log.i("result", x + "-" + y + "=" + finalResult);//此处的长度取决于小数点后面位数大的return finalResult;}int getLengthOfInt(double x, double y) {int lengthOfInt;int intX = (int) x;  //x的整数部分int intY = (int) y;  //y的整数部分lengthOfInt = String.valueOf(intX - intY).length();   //结果整形部分的位数 = 相减后整形的位数return lengthOfInt;}int getLengthOfDecimal(double x) {return String.valueOf(x).split("\\.")[1].length(); //计算x小数点后面的位数}
public class Result {public static double getRes(String expression) {System.out.println(expression.length());expression = expression.replace("sin", "s");expression = expression.replace("÷", "/");expression = expression.replace("×", "*");ArrayStack stack=new ArrayStack(20);String exp = "";int count = 0;char[] chars = expression.toCharArray();while (count < chars.length) {if (count == 0 && chars[count] == '-') {chars[count] = '#';}if (count >= 1 && chars[count] == '-' && chars[count - 1] == '(') {chars[count] = '#';}if (count >= 1 && chars[count] == '-' && stack.priority(chars[count-1])>stack.priority(chars[count])) {chars[count] = '#';}exp += chars[count];count++;}expression=exp;//创建两个栈,数栈,一个符号栈ArrayStack numStack = new ArrayStack(20);ArrayStack operatorStack = new ArrayStack(20);//定义需要的相关变量int index = 0;//用于扫描double num1 = 0;double num2 = 0;int oper = 0;double res = 0;char ch = ' '; //将每次扫描得到char保存到chString keepNum = ""; //用于拼接 多位数//开始while循环的扫描expressionwhile (true) {//依次得到expression 的每一个字符ch = expression.substring(index, index + 1).charAt(0);//判断ch是什么,然后做相应的处理if (operatorStack.isLeftBrackets(ch)) {   //如果是左括号//直接入符号栈..operatorStack.push(ch);} else if (operatorStack.isRightBrackets(ch)) {  //如果是右括号while (operatorStack.peek() != '(') {  //循环直到能够到达 '(' 处oper = (int) operatorStack.pop();if (oper == 's' ||oper == '!' ||oper == 'v' ||oper == '#' ||oper == '%') {  //如果栈顶为三角函数、阶乘或者是开根num1 = numStack.pop();res = numStack.mixedOperation(num1, oper);//把运算的结果如数栈numStack.push(res);} else {num1 = numStack.pop();num2 = numStack.pop();res = operatorStack.cal(num1, num2, oper);//把运算的结果如数栈numStack.push(res);}}//然后将当前栈顶的操作符出符号栈----其实也就是 '(' 出栈operatorStack.pop();} else if (operatorStack.isOper(ch)) {   //如果是运算符if (operatorStack.isEmpty() || operatorStack.peek() == '(') {//如果符号栈为空,或者栈顶为'('operatorStack.push(ch);} else if (operatorStack.priority(ch) > operatorStack.priority((int) operatorStack.peek())) {//如果当前优先级比栈顶优先级高,直接入符号栈.operatorStack.push(ch);} else {while (!operatorStack.isEmpty() &&(operatorStack.priority(ch) <= operatorStack.priority((int) operatorStack.peek()))) {oper = (int) operatorStack.pop();if (!operatorStack.isEmpty() && (operatorStack.peek() == '!' ||operatorStack.peek() == 's' ||operatorStack.peek() == 'v' ||operatorStack.peek() == '#' ||operatorStack.peek() == '%')) {num1 = numStack.pop();res = numStack.mixedOperation(num1, oper);numStack.push(res);//入栈} else {if (oper == 's' ||oper == '!' ||oper == 'v' ||oper == '#' ||oper == '%') {  //如果栈顶为三角函数、阶乘或者是开根num1 = numStack.pop();res = numStack.mixedOperation(num1, oper);//把运算的结果如数栈numStack.push(res);} else {num1 = numStack.pop();num2 = numStack.pop();res = numStack.cal(num1, num2, oper);//把运算的结果如数栈numStack.push(res);}}}//然后将当前的操作符入符号栈operatorStack.push(ch);}} else if (operatorStack.isPoint(ch) || operatorStack.isNum(ch)) {   //如果是数或者是小数点,则直接入数栈//numStack.push(ch - 48); // "1+3" '1' => 1//1. 当处理多位数时,不能发现是一个数就立即入栈,因为可能是多位数//2. 在处理数,需要向expression的表达式的index 后再看一位,如果是数就进行扫描,如果是符号才入栈//3. 因此我们需要定义一个变量 字符串,用于拼接//处理多位数keepNum += ch;//如果ch已经是expression的最后一位,就直接入栈if (index == expression.length() - 1) {numStack.push(Double.parseDouble(keepNum));} else {//判断下一个字符是不是数字,如果是数字,就继续扫描,如果是运算符,则入栈//注意是看后一位,不是index++if (operatorStack.isOper(expression.substring(index + 1, index + 2).charAt(0))|| operatorStack.isRightBrackets(expression.substring(index + 1, index + 2).charAt(0))) {//如果后一位是运算符,则入栈 keepNum = "1" 或者 "123"numStack.push(Double.parseDouble(keepNum));//最后keepNum必须清空keepNum = "";}}} else if (!operatorStack.isEmpty() && (operatorStack.peek() == 's' ||operatorStack.peek() == '!' ||operatorStack.peek() == 'v' ||operatorStack.peek() == '#' ||operatorStack.peek() == '%')) {   //如果栈顶为三角函数算式、开根或者是阶乘oper = (int) operatorStack.pop();num1 = numStack.pop();res = numStack.mixedOperation(num1, oper);//把运算的结果入数栈numStack.push(res);}//让index + 1, 并判断是否扫描到expression最后.index++;if (index >= expression.length()) {break;}}//当表达式扫描完毕,就顺序的从 数栈和符号栈中pop出相应的数和符号,并运行.while (true) {//如果符号栈为空,则计算到最后的结果, 数栈中只有一个数字【结果】if (operatorStack.isEmpty()) {break;}if (operatorStack.peek() == 's' ||operatorStack.peek() == '!' ||operatorStack.peek() == 'v' ||operatorStack.peek() == '#' ||operatorStack.peek() == '%') {    //如果栈顶为三角函数算式oper = (int) operatorStack.pop();num1 = numStack.pop();res = numStack.mixedOperation(num1, oper);numStack.push(res);//入栈} else {num1 = numStack.pop();num2 = numStack.pop();oper = (int) operatorStack.pop();res = numStack.cal(num1, num2, oper);numStack.push(res);//入栈}}//将数栈的最后数,pop出,就是结果double res2 = numStack.pop();System.out.println(res2+"ll");return res2;}

求点赞+关注偶

心心念念的安卓简单和多功能计算器来了相关推荐

  1. android dpi计算器,安卓多功能计算器 One++ Calculator 1.7.5 中文多语免费版

    安卓多功能计算器 One++ Calculator 中文解锁版由大眼仔~旭(www.dayanzai.me)发布.One++ Calculator 不是普通的计算器,而是数字公式计算的集合.现在市面上 ...

  2. android角度计算器,Calckit高级版一款安卓多功能计算器,内置高度定制的科学计算器...

    前言 手机中的计算器功能你多久用一次呢,我相信对于多数人来说计算器是一个低频使用软件. 其原因可能是用不上计算功能也很可能是单一的计算功能并不能满足你对于计算的需求. 那么如果现在有一款可以完成中学到 ...

  3. php编网页版计算器,php编程实现简单的网页版计算器功能示例

    本文实例讲述了php编程实现简单的网页版计算器功能.分享给大家供大家参考,具体如下: 如何通过php代码来实现一个网页版的计算器的简单功能?下面就是通过php基础知识来做的网页版计算器,功能只有&qu ...

  4. php编网页版计算器,php实现简单的网页版计算器功能的方法

    这篇文章主要介绍了php编程实现简单的网页版计算器功能,涉及php简单表单操作与数值运算相关实现技巧,需要的朋友可以参考下 如何通过php代码来实现一个网页版的计算器的简单功能?下面就是通过php基础 ...

  5. 利用Bmob快速实现安卓的简单登陆注册功能Bmobsdk3.6.9版本亲测可用(详细图文攻略附带处理小bug)

    前言:从其他人的留言中我知道Bmob这个云数据库,之前我一直在自己写后台但是发现太慢了要学的东西超级多,脚手架也不知道为什么老是搭不上很蛋疼,然后春节又必须回来老家山区里面有些事情耽搁了后台也凉了,后 ...

  6. JavaGUI:多功能计算器(一)--AWT框架按钮(完整代码)

    简单的可变窗体计算器v0.32 [DbY–更少代码&更多功能] 精简源码+详细注释,一看便懂. [背景简介] 我一直相信,一个简单的充满趣味的入门程序即可为初学者开启一扇学习的大门,而不必非得 ...

  7. JavaGUI:多功能计算器(四)--Swing实现双语悬停提示(源码升级说明)

    JavaGUI:多功能计算器(四)–Swing实现双语悬停提示(源码升级说明) [背景提示] AWT(Abstract Windowing Toolkit): 抽象窗口工具包AWT是Java的平台独立 ...

  8. JavaGUI:多功能计算器(五)--Swing实现双语数据包+菜单切换(完整源码+EXE下载)

    JavaGUI:多功能计算器(五)–Swing实现双语数据包+菜单切换(完整源码+EXE下载) 本文资源下载: 程序源码及可独立运行的EXE文件自解压包(32bit): 多功能计算器v0.41[双语界 ...

  9. android6.0.1隐藏功能,安卓6.0系统界面调谐器怎么使用?安卓6.0隐藏功能开启和使用方法[多图]...

    安卓6.0推送有一段时间了,很多用户对其新增功能还不太了解吧!今天友情下载小麦给大家带来的是安卓6.0隐藏功能开启和使用方法,希望可以帮到大家,现在就跟随小麦一起看看吧!!! 要开启安卓6.0的隐藏功 ...

  10. Qt多功能计算器(四)——base64加密和解密

    项目介绍 本篇文章的内容是Qt多功能计算器的第四个功能,base64的加密和解密,这可能是除对话框外,这个项目中最简单.代码量最少的界面(因为项目还没有写完,所以我不能确定这一定是最简单的界面). 界 ...

最新文章

  1. 'eval' is null or not an object
  2. do还是doing imagine加to_啤酒,还是精酿好
  3. 简单比对照片是否相同_小新说法 | 如何认定商标是否侵权?
  4. Oracle 大规模 delete,update 操作 注意事项
  5. LeetCode 940. 不同的子序列 II(动态规划)
  6. 深入理解 Cilium 的 eBPF(XDP)收发包路径:数据包在Linux网络协议栈中的路径
  7. 消息中间件学习总结(3)——RocketMQ之十分钟入门RocketMQ
  8. java day35【Bootstrap】
  9. 任务35:JWT 认证授权介绍
  10. windos未能链接服务器,提示Windows没法连接到System Event Notification Service服务
  11. Oracle ADF 12.2.1 使用报告
  12. 44.网络安全渗透测试—[穷举篇7]—[网站会员批量登录穷举]
  13. node+express+mysql搭建一个系统
  14. wow转服务器微信支付,魔兽打团本成就,打到一半,发微信支付宝要钱,真国服之耻!...
  15. 客户端timewait
  16. jquery返回上一页,前一页
  17. java thread dump
  18. mysql数据库名称中包含短横线的对应方式
  19. 山西经济林栽培技术之形考作业三
  20. Android 9-patch 九图的制作与使用

热门文章

  1. jdk安装后怎么使用_jdk安装后怎么打开java
  2. 网格搜索的原理以及实战以及相关API(GridSearchCV)
  3. 简易PROTUES的定时器仿真
  4. ubuntu 搭建 smtp 邮件服务器
  5. 有DMX512协议控制的整套硬件解决方案吗?来看一下,舞台灯光同步视频播放DMX控制台
  6. Android官方文档—APP组件(Content Providers)(Contacts Provider)
  7. 用友NC报表行数能否配置
  8. moodle php代码解读_Moodle插件开发笔记
  9. android 开机优化(类和资源预加载优化)
  10. 手机wap网站制作教程