• 简易计算器的java实现


    伪代码

    public class MainTestwei
    {
        定义两个数组,List<Double> number和 List<Character>calculation分别用来装数字和 计算符
         //与老师上课讲的入栈出栈差不多
         public Count() {}方法初始化number和 calculation
        public void init()方法清空数组
        private boolean check()方法检查输入算式是否合法同时检查数字个数是否比计算符个数大1
        private int findCount(String text, String regex, int len)方法返回输入的算式中匹配正则表达式得到元素的个数
        private void setValue()给number和 calculation数组定初值(应用正则表达式)
        private double sum()用case语句进行求值,注意*/在前+-在后
        public String out(String text)判断是否合法,合法输出结果,不合法输出error
    }
    
    

    各个方法的依次实现

    1.初始化number和 calculation

    public Count() {
            number = new ArrayList<>();
            calculation = new ArrayList<>();
    
        }
    

    其中已经提前定义过

    private List<Double> number;
        private List<Character> calculation;
        private String text;
    

    即number是型的。calculation
    字符型的。

    2.private int findCount(String text, String regex, int len)方法返回输入的算式中匹配正则表达式得到元素的个数。代码如下

     private int findCount(String text, String regex, int len) {
            int count = 0;
            Pattern compile = Pattern.compile(regex);
            Matcher matcher = compile.matcher(text);
            while (matcher.find()) {
                count++;
                if (len > 0) {//
                    System.out.println(matcher.group().length());
                    if (matcher.group().length() != len)//不理解matcher.group().length()
                    {
                        System.out.println(matcher.group().length());
                        return -1;
                    }
    
    
                }
            }
            return count;
    

    其中

    matcher.group().length()
    

    是关于正则表达式中含有括号的个数。如
    regex1 = "[+-*/]+"它的matcher.group().length()即为1.因为中。间没有()分割。

    regex = "d+"它的matcher.group().length()也为1.

    matcher.group()即为一次匹配得到的所有,不考虑括号()问题,而matcher.group(i)即为匹配第i个括号中所得到的表达式。

    其中

    if (len > 0) {//为什么
                    System.out.println(matcher.group().length());
                    if (matcher.group().length() != len)//不理解matcher.group().length()
                    {
                        return -1;
                    }
    

    是为了避免式子中出现括号。

    3.private boolean check()方法检查输入算式是否合法同时检查数字个数是否比计算符个数大1。
    代码如下

    private boolean check() {
            if (text == null || !text.matches("[0-9+\-*/]+"))//正则表达式不太理解
                return false;
    
            String regex= "\d+";
            String regex1 = "[+\-*/]+";
            if (findCount(text, regex1, 1) == -1)
                return false;
            return findCount(text, regex1, 1) == findCount(text, regex, 0) - 1;
    
        }
    

    regex是匹配数字用的正则表达式,regex1是匹配+ -/的正则表达式,而-/ 都需要转义,故在前面加上//。

    如果出现括号则error,否则如果数字个数比字符个数多1,则正确,返回true。

    4.private void setValue()给number和 calculation数组定初值(应用正则表达式),代码如下:

       private void setValue() {
            Pattern compile = Pattern.compile("\d+");
            Matcher matcher = compile.matcher(text);
            while (matcher.find()) {
                number.add(Double.parseDouble(matcher.group()));
            }
            Pattern compile1 = Pattern.compile("[+-/*]");
            Matcher matcher1 = compile1.matcher(text);
            while (matcher1.find()) {
                calculation.add(matcher1.group().charAt(0));
            }
        }
    

    matcher.group()代表的就是匹配的内容,因为数字与字符交替排列,故每次add matcher.group()即可,转化为Double型。

    5.private double sum()用case语句进行求值,注意*/在前+-在后。
    代码如下:

    private double sum() {
    
            for (int i = 0; i < calculation.size(); i++) {
                char c = calculation.get(i);
                switch (c) {
                    case '*':
                        number.set(i, number.get(i) * number.get(i + 1));
                        number.remove(i + 1);
                        calculation.remove(i);
                        i -= 1;//为什么要加i=i-1;
                        break;
                    case '/':
                        number.set(i, (Double) number.get(i) / number.get(i + 1));
                        number.remove(i + 1);
                        calculation.remove(i);
                        i -= 1;
                        break;
                }
            }
    
            for (int i = 0; i < calculation.size(); i++) {
                char c = calculation.get(i);
                switch (c) {
                    case '+':
                        number.set(i, number.get(i) + number.get(i + 1));
                        number.remove(i + 1);
                        calculation.remove(i);
                        i -= 1;
                        break;
                    case '-':
                        number.set(i, (Double) number.get(i) - number.get(i + 1));
                        number.remove(i + 1);
                        calculation.remove(i);
                        i -= 1;
                        break;
                }
            }
    
            return number.get(0);
        }
    

    其中为什么需要i=i-1?
    因为上面有 for (int i = 0; i < calculation.size(); i++)循环,当你执行 calculation.remove(i);之后,i所指向的已经是下一个符号或者是数字了,但因为for循环仍然需要i++,故要提前把i-1。

    此处与栈的操作类型有几分相似之处,再MyDC.java中,经过

    while (tokenizer.hasMoreTokens()) //进行遍历
    {
                token = tokenizer.nextToken();
               //token是单字符的字符串
               //如果是运算符,调用isOperator
                if (isOperator(token)==true) {
                    op2=stack.pop();
                    op1=stack.pop();
                    //从栈中弹出操作数2
                    //从栈中弹出操作数1
                    result=evalSingleOp(token.charAt(0),op1,op2);
                    //根据运算符和两个操作数调用evalSingleOp计算result;
                    stack.push(result);
                    //计算result入栈;
                }
                else//如果是操作数
                {
                    stack.push(Integer.parseInt(token));//需要转化为int型
                }
                //操作数入栈;
            }
    
    
    

    6.public String out(String text)判断是否合法,合法输出结果,不合法输出error
    代码如下

    public String out(String text) {
            init();
            if (getString(text)) {
                return sum() +"";//sum()为double类型,需要转化为字符串类型,则加上“”即可
    
            } else {
                return "error";
            }
    
        }
    

    其中init()用clear()方法即可。

    最终代码

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class MainTest {
        public static void main(String[] args) {
            while (true) {
                Scanner input = new Scanner(System.in);
                String text = input.nextLine();
                String string = new Count().out(text);
                System.out.println(string);
            }
    
        }
    
    }
    
    class Count {
        private List<Double> number;
        private List<Character> calculation;
        private String text;
    
        public Count() {
            number = new ArrayList<>();
            calculation = new ArrayList<>();
    
        }
    
        public String out(String text) {
            init();
            if (getString(text)) {
                return sum() +"";
    
            } else {
                return "error";
            }
    
        }
    
        private double sum() {
    
            for (int i = 0; i < calculation.size(); i++) {
                char c = calculation.get(i);
                switch (c) {
                    case '*':
                        number.set(i, number.get(i) * number.get(i + 1));
                        number.remove(i + 1);
                        calculation.remove(i);
                        i -= 1;//为什么要加i=i-1;
                        break;
                    case '/':
                        number.set(i, (Double) number.get(i) / number.get(i + 1));
                        number.remove(i + 1);
                        calculation.remove(i);
                        i -= 1;
                        break;
                }
            }
    
            for (int i = 0; i < calculation.size(); i++) {
                char c = calculation.get(i);
                switch (c) {
                    case '+':
                        number.set(i, number.get(i) + number.get(i + 1));
                        number.remove(i + 1);
                        calculation.remove(i);
                        i -= 1;
                        break;
                    case '-':
                        number.set(i, (Double) number.get(i) - number.get(i + 1));
                        number.remove(i + 1);
                        calculation.remove(i);
                        i -= 1;
                        break;
                }
            }
    
            return number.get(0);
        }
    
        public void init() {
            number.clear();//清空数组
            calculation.clear();
        }
    
        public boolean getString(String text) {
            this.text = text;
            if (check()) {
    
                setValue();
                return true;
            }
            return false;
        }
    
        private void setValue() {
            Pattern compile = Pattern.compile("\d+");
            Matcher matcher = compile.matcher(text);
            while (matcher.find()) {
                number.add(Double.parseDouble(matcher.group()));
            }
            Pattern compile1 = Pattern.compile("[+-/*]");
            Matcher matcher1 = compile1.matcher(text);
            while (matcher1.find()) {
                calculation.add(matcher1.group().charAt(0));
            }
        }
    
        private boolean check() {
            if (text == null || !text.matches("[0-9+\-*/]+"))//正则表达式不太理解
                return false;
    
            String regex = "\d+";
            String regex1 = "[+\-*/]+";
            if (findCount(text, regex1, 1) == -1)
                return false;
            return findCount(text, regex1, 1) == findCount(text, regex, 0) - 1;
    
        }
        private int findCount(String text, String regex, int len) {
            int count = 0;
            Pattern compile = Pattern.compile(regex);
            Matcher matcher = compile.matcher(text);
            while (matcher.find()) {
                count++;
                if (len > 0) {//为什么
                    System.out.println(matcher.group().length());
                    if (matcher.group().length() != len)//不理解matcher.group().length()
                    {
                        return -1;
                    }
    
    
                }
            }
            return count;
        }
    
    }
    
  • 相关阅读:
    [开发笔记]-使用bat命令来快速安装和卸载Service服务
    [开发笔记]-多线程异步操作如何访问HttpContext?
    [开发笔记]-Windows Service服务相关注意事项
    [开发笔记]-VS2012打开解决方案崩溃或点击项目崩溃
    Chrome 开发者工具有了设备模拟器
    Mysql查看数据库表容量大小
    golang操作mysql数据库
    golang命令和VSCode配置
    golang广度优先算法-走迷宫
    golang爬取免费代理IP
  • 原文地址:https://www.cnblogs.com/paypay/p/6803802.html
Copyright © 2020-2023  润新知