应用网格布局设计的计算器

应用网格布局设计的计算器_第1张图片

1.界面设计

采用书本代码设计页面。

2.功能设计

按照按钮点击事件的套路,每当点击按钮时,就会执行onClick()的方法,我们在这个方法里加入个switch循环,每个case:是按钮的id,我们申请个private StringBuilder的字符串。每按一个按钮,只要满足要求,不是错误的输入,就调用append()方法,将按钮的值当字符存入这个字符串中,当用户按到等号时,调用另一个java文件的自己写的处理的类

3.详细代码

界面部分代码不再重复,以下为功能设计部分代码。

MainActivity.java中的

package com.example1.asus.secondapp;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.util.Arrays;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {


    private TextView text;
    private Button bt_1;
    private Button bt_2;
    private Button bt_3;
    private Button bt_4;
    private Button bt_5;
    private Button bt_6;
    private Button bt_7;
    private Button bt_8;
    private Button bt_9;
    private Button bt_0;
    private Button bt_clean;
    private Button bt_add;
    private Button bt_sub;
    private Button bt_multiply;
    private Button bt_divide;
    private Button bt_dot;
    private Button bt_sum;
    private StringBuilder pending = new StringBuilder();
    protected void onCreate(Bundle savedInstanceState) {


        super.onCreate(savedInstanceState);

        setContentView();


        initView();

    }

    private void setContentView() {
    }
    private Object findViewByid(int text) {
        return null;
    }
    private void initView() {

        text = (TextView)findViewByid(R.id.text);
        bt_1 = (Button)findViewByid(R.id.bt1);
        bt_2 = (Button)findViewByid(R.id.bt2);
        bt_3 = (Button)findViewByid(R.id.bt3);
        bt_4 = (Button)findViewByid(R.id.bt4);
        bt_5 = (Button)findViewByid(R.id.bt5);
        bt_6 = (Button)findViewByid(R.id.bt6);
        bt_7 = (Button)findViewByid(R.id.bt7);
        bt_8 = (Button)findViewByid(R.id.bt8);
        bt_9 = (Button)findViewByid(R.id.bt9);
        bt_0 = (Button)findViewByid(R.id.bt0);
        bt_clean = (Button)findViewByid(R.id.bt_clear);
        bt_add = (Button)findViewByid(R.id.bt_add);
        bt_sub = (Button)findViewByid(R.id.bt_sub);
        bt_multiply = (Button)findViewByid(R.id.bt_multiply);
        bt_divide = (Button)findViewByid(R.id.bt_divide);
        bt_sum = (Button)findViewByid(R.id.bt_sum);
        bt_dot = (Button)findViewByid(R.id.bt_dot);


        bt_0.setOnClickListener(this);

        bt_1.setOnClickListener(this);

        bt_2.setOnClickListener(this);

        bt_3.setOnClickListener(this);

        bt_4.setOnClickListener(this);

        bt_5.setOnClickListener(this);

        bt_6.setOnClickListener(this);

        bt_7.setOnClickListener(this);

        bt_8.setOnClickListener(this);

        bt_9.setOnClickListener(this);

        bt_dot.setOnClickListener(this);

        bt_add.setOnClickListener(this);

        bt_sum.setOnClickListener(this);

        bt_multiply.setOnClickListener(this);

        bt_divide.setOnClickListener(this);

        bt_clean.setOnClickListener(this);

        bt_sub.setOnClickListener(this);


    }




    public void onClick(View v) {

        int last = 0;

        if(pending.length()!=0)

        {

            last = pending.codePointAt(pending.length()-1);


        }

        switch (v.getId()) {

            case R.id.bt0:

                pending = pending.append("0");

                text.setText(pending);

                break;
            case R.id.bt1:

                pending = pending.append("1");

                text.setText(pending);

                break;
            case R.id.bt2:

                pending = pending.append("2");

                text.setText(pending);

                break;
            case R.id.bt3:

                pending = pending.append("3");

                text.setText(pending);

                break;
            case R.id.bt4:

                pending = pending.append("4");

                text.setText(pending);

                break;
            case R.id.bt5:

                pending = pending.append("5");

                text.setText(pending);

                break;
            case R.id.bt6:

                pending = pending.append("6");

                text.setText(pending);

                break;
            case R.id.bt7:

                pending = pending.append("7");

                text.setText(pending);

                break;
            case R.id.bt8:

                pending = pending.append("8");

                text.setText(pending);

                break;
            case R.id.bt9:

                pending = pending.append("9");

                text.setText(pending);

                break;
            case R.id.bt_add:

                //if (last >= '0' && last <= '9' ) {

                pending = pending.append("+");

                // }

                text.setText(pending);

                break;
            case R.id.bt_sub:

                //if (last >= '0' && last <= '9' ) {

                pending = pending.append("-");

                // }

                text.setText(pending);

                break;
            case R.id.bt_multiply:

                //if (last >= '0' && last <= '9' ) {

                pending = pending.append("*");

                // }

                text.setText(pending);

                break;
            case R.id.bt_divide:

                //if (last >= '0' && last <= '9' ) {

                pending = pending.append("/");

                // }

                text.setText(pending);

                break;
            case R.id.bt_dot:

                if (judje1()) {

                    pending = pending.append(".");

                    text.setText(pending);

                }

                break;
            case R.id.bt_clear: //清空

                pending = pending.delete(0, pending.length());

                text.setText(pending);

                break;

            case R.id.bt_sum: // =等于

                if ((pending.length() > 1)) {

                    InfixInToDuffix inf = new InfixInToDuffix();

                    String jieguo;

                    try {

                        String a = inf.toSuffix(pending);

                        jieguo = inf.dealEquation(a);


                    } catch (Exception ex) {

                        jieguo = "出错";

                    }

                    text.setText(pending + "=" + jieguo);

                    pending = pending.delete(0, pending.length());

                    if (Character.isDigit(jieguo.charAt(0))) {

                        pending = pending.append(jieguo);

                    }

                }

                break;

            default:

                break;

        }

    }
    private boolean judje1() {

        String a = "+-*/.";

        int[] b = new int[a.length()];

        int max;

        for (int i = 0; i < a.length(); i++) {

            String c = "" + a.charAt(i);

            b[i] = pending.lastIndexOf(c);

        }

        Arrays.sort(b);

        if (b[a.length() - 1] == -1) {

            max = 0;

        } else {

            max = b[a.length() - 1];

        }

        if (pending.indexOf(".", max) == -1) {

            return true;

        } else {

            return false;


        }

    }

    private int judje2(){

        int a=0,b=0;

        for(int i = 0 ; i < pending.length() ;i++){

            if(pending.charAt(i)=='(' ) {

                a++;

            }

            if(pending.charAt(i)==')' ) {

                b++;

            }

        }

        if(a == b)

            return 0;

        if(a > b)

            return 1;

        return 2;

    }





}

 

在InfixInToDuffix.java中,把用户输入的数字和运算符全部在peng这个字符串里,把这个字符串里面的计算式子从中缀表达式转化为后缀表达式。

package com.example1.asus.secondapp;
import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.lang.*;

import java.util.ArrayList;

import java.util.*;
public class InfixInToDuffix {

//使用集合定义好符号的运算优先级别

    private static final Mapbasic =new HashMap();

    static {

        basic.put('-',1);

        basic.put('+', 1);

        basic.put('*', 2);

        basic.put('/', 2);

        basic.put('(', 0);//在运算中  ()的优先级最高,但是此处因程序中需要 故设置为0

    }



    //将中缀表达式转换为后缀表达式

    public String toSuffix(StringBuilder infix){

        List queue = new ArrayList();                                    //定义队列  用于存储 数字  以及最后的  后缀表达式

        List stack = new ArrayList();                //定义栈    用于存储  运算符  最后stack中会被 弹空



        char[] charArr = infix.substring(0,infix.length()).trim().toCharArray();//字符数组  用于拆分数字或符号

        String standard = "*/+-()";                    //判定标准 将表达式中会出现的运算符写出来

        char ch = '&';                                 //在循环中用来保存 字符数组的当前循环变量的  这里仅仅是初始化一个值  没有意义

        int len = 0;                                   //用于记录字符长度 【例如100*2,则记录的len为3 到时候截取字符串的前三位就是数字】

        for (int i = 0; i < charArr.length; i++) {                                  //开始迭代


            ch = charArr[i];                                                      //保存当前迭代变量

            if(Character.isDigit(ch)) {                                           //如果当前变量为 数字

                len++;

            }else if(ch == '.'){                                                   //如果当前变量为  .  会出现在小数里面

                len++;

            }else if(standard.indexOf(ch) != -1) {                                //如果是上面标准中的 任意一个符号

                if(len > 0) {                                                        //长度也有

                    queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i)));    //说明符号之前的可以截取下来做数字

                    len = 0;                                                          //长度置空

                }

                if(ch == '(') {                                                            //如果是左括号

                    stack.add(ch);                                                        //将左括号 放入栈中

                    continue;                                                            //跳出本次循环  继续找下一个位置

                }

                if (!stack.isEmpty()) {                                                    //如果栈不为empty

                    int size = stack.size() - 1;                                        //获取栈的大小-1  即代表栈最后一个元素的下标

                    boolean flag = false;                                                //设置标志位

                    while (size >= 0 && ch == ')' && stack.get(size) != '(') {            //若当前ch为右括号,则 栈里元素从栈顶一直弹出,直到弹出到 左括号

                        queue.add(String.valueOf(stack.remove(size)));                    //注意此处条件:ch并未入栈,所以并未插入队列中;同样直到找到左括号的时候,循环结束了,所以左括号也不会放入队列中【也就是:后缀表达式中不会出现括号】

                        size--;                                                            //size-- 保证下标永远在栈最后一个元素【栈中概念:指针永远指在栈顶元素】

                        flag = true;                                                    //设置标志位为true  表明一直在取()中的元素

                    }

                    if(ch==')'&&stack.get(size) == '('){

                        flag = true;

                    }

                    while (size >= 0 && !flag && basic.get(stack.get(size)) >= basic.get(ch)) {    //若取得不是()内的元素,并且当前栈顶元素的优先级>=对比元素 那就出栈插入队列

                        queue.add(String.valueOf(stack.remove(size)));                    //同样  此处也是remove()方法,既能得到要获取的元素,也能将栈中元素移除掉

                        size--;

                    }

                }

                if(ch != ')') {                                                            //若当前元素不是右括号

                    stack.add(ch);                                                        //就要保证这个符号 入栈

                } else {                                                                //否则就要出栈 栈内符号

                    stack.remove(stack.size() - 1);

                }

            }

            if(i == charArr.length - 1) {                                                //如果已经走到了  中缀表达式的最后一位

                if(len > 0) {                                                            //如果len>0  就截取数字

                    queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len+1, i+1)));

                }
                int size = stack.size() - 1;                                            //size表示栈内最后一个元素下标

                while (size >= 0) {                            //一直将栈内  符号全部出栈 并且加入队列中  【最终的后缀表达式是存放在队列中的,而栈内最后会被弹空】

                    queue.add(String.valueOf(stack.remove(size)));

                    size--;

                }

            }


        }

        String a = queue.toString();

        return a.substring(1,a.length()-1);

    }





    public String dealEquation(String equation){


        String [] arr = equation.split(", ");                                    //根据, 拆分字符串

        List list = new ArrayList();                            //用于计算时  存储运算过程的集合【例如list中当前放置  100   20  5  /  则取出20/5 最终将结果4存入list   此时list中结果为  100  4 】



        for (int i = 0; i < arr.length; i++) {                                    //此处就是上面说的运算过程, 因为list.remove的缘故,所以取出最后一个数个最后两个数  都是size-2

            int size = list.size();

            switch (arr[i]) {

                case "+": double a = Double.parseDouble(list.remove(size-2))+ Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(a));     break;

                case "-": double b = Double.parseDouble(list.remove(size-2))- Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(b));     break;

                case "*": double c = Double.parseDouble(list.remove(size-2))* Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(c));     break;

                case "/": double d = Double.parseDouble(list.remove(size-2))/ Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(d));       break;

                default: list.add(arr[i]);     break;                                    //如果是数字  直接放进list中

            }

        }


        return list.size()


                == 1 ? list.get(0) : "运算失败" ;                    //最终list中仅有一个结果,否则就是算错了

    }


}

实验结果

应用网格布局设计的计算器_第2张图片

感想:

原因尚不明确的软件停止运行,让几个晚上通宵的成果付之一炬,结果还是自己基础太差,能力不足,但是这次主要也能熟悉了一下网格布局的用法,以及相应代码的编写,这对于java基础极差的我来说,有一定的帮助,希望能变得更好。

你可能感兴趣的:(应用网格布局设计的计算器)