四则运算

摘要:

1、第一阶段目标:重构四则运算-- 能把计算的功能封装起来,通过API 接口调用计算方法。定义一个计算核心类:把四则运算的计算功能包装在一个模块中 (这个模块可以是一个类 Class,  一个DLL等等)。“计算核心”模块和调用类它的其他模块之间是什么关系呢? 它们要通过一定的API (Application Programming Interface) 来和其他模块交流。这个API 接口应该怎么设计呢? 可以从下面的最简单的接口开始:Calc()

这个Calc 函数接受字符串的输入(字符串里就是运算式子,例如 “ 5+3.5“,  “7/8 – 3/8 ”,  “3 + 90 * (-0.3)“  等等),这个模块的返回值是一个字符串,例如,前面几个例子的结果就是 ( ”17.5“, “ 1/2”, “-24“).

2 第二阶段目标 - 通过测试程序和API 接口测试其简单的加减乘除功能。并能看到代码覆盖率。可以扩展 Calc() 的定义,让它接受一个新的参数 “precision”,  或者可以启用一个新的函数 Setting()。最多4 个运算符数值范围是 -1000 到 1000精度是小数点后两位怎么通过API 告诉我们的模块呢?  我们当然可以用函数的参数直接传递,但是参数的组合很多,怎么定义好参数的规范呢?   建议大家考虑用 XML 来传递这些参数。增加了新的Setting() 函数之后,要让模块支持这样的参数,同时,还要保证原来的各个测试用例继续正确地工作。

3第三阶段目标 – 定义异常处理。如果输入是有错误的,例如 “1 ++ 2”, 在数值范围是 -1000 .. 1000 的时候,传进去 “10000 + 32768 * 3”,  或者是 “ 248.04 / 0”  怎么办? 怎么告诉函数的调用者 “你错了”?  把返回的字符串定义为 “-1” 来表示? 那么如果真的计算结果是 “-1” 又怎么处理呢?建议这个时候,要定义各种异常 (Exception), 让 Core 在碰到各种异常情况的时候,能告诉调用者 - 你错了! 当然,这个时候,同样要进行下面的增量修改:定义要增加什么功能 - 例如:支持 “运算式子格式错误” 异常,写好测试用例,传进去一个错误的式子,期望能捕获这个 异常。 如果没有,那测试就报错。在 Core 模块中实现这个功能,测试这个功能, 同时测试所有以前的功能,保证以前的功能还能继续工作 (没有 regression), 确认功能完成,继续下一个功能。

 

代码:

package yunsuan;

import java.util.*;

public class Cal {

    public char[] op = {'+','-','*','/','(',')'};
    public String[] strOp = {"+","-","*","/","(",")"};
    public boolean isOp(char c){
        for(int i=0;i<op.length;i++){
            if(op[i]==c){
                return true;
            }
        }
        return false;
    }
    public boolean isOp(String s){
        for(int i=0;i<strOp.length;i++){
            if(strOp[i].equals(s)){
                return true;
            }
        }
        return false;
    }
    /*
     * 处理输入的字符串
     * 将他分成一个一个的字符串
     */
    public List<String> work(String str)
    {
        List<String> list = new ArrayList<String>();
        char c;
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<str.length();i++){
            c = str.charAt(i);
            if(!isOp(c)){
                sb.append(c);
            }
            else{
                if(sb.toString().length()>0){
                    list.add(sb.toString());
                    sb.delete(0, sb.toString().length());
                }
                list.add(c+"");
            }
        }
        if(sb.toString().length()>0){
            list.add(sb.toString());
            sb.delete(0, sb.toString().length());
        }
        return list;
    }
    /*
     * 输出检测
     */
    public void printList(List<String> list){
        for(String o:list){
            System.out.print(o+" ");
        }
    }

    /*
     * 
     * 中缀表达式转换成后缀表达式
     */
    public List<String> translate(List<String> str) 
    {
        List<String> list=new ArrayList<String>();
        Stack<String> stack = new Stack<String>();//暂存操作符
        for(int i=0;i<str.size();i++)
        {
            String s=str.get(i);
            if(s.equals("(")){
                stack.push(s);
            }else if(s.equals("*")||s.equals("/")){
                stack.push(s);
            }else if(s.equals("+")||s.equals("-"))
            {
                if(s.equals("-")&&stack.peek().equals("("))
                {
                    i++;
                    list.add("-"+str.get(i));
                    continue;
                }
                if(!stack.empty())
                {
                    while(!(stack.peek().equals("(")))
                    {
                        list.add(stack.pop());
                        if(stack.empty())
                        {
                            break;
                        }
                    }
                    stack.push(s);
                }
                else
                {
                    stack.push(s);
                }
            }
            else if(s.equals(")"))
            {
                while(!(stack.peek().equals("(")))
                {
                    list.add(stack.pop());
                }
                stack.pop();
            }
            else
            {
                list.add(s);
            }
            if(i==str.size()-1)
            {
                while(!stack.empty())
                {
                    list.add(stack.pop());
                }
            }
        }
        return list;
    }

    /*
     * 后缀表达式的计算
     */
    public Double docal(List<String> list)
    {
        Stack<Double> stack=new Stack<Double>();
        for(int i=0;i<list.size();i++)
        {
            String s = list.get(i);
            Double t=0.0;
            if(!isOp(s))
            {
                t =Double.parseDouble(s);
                stack.push(t);
            }
            else
            {
                if(s.equals("+"))
                {
                    Double a1 = stack.pop();
                    Double a2 = stack.pop();
                    Double v = a2+a1;
                    stack.push(v);
                }
                else if(s.equals("-"))
                {
                    Double a1 = stack.pop();
                    Double a2 = stack.pop();
                    Double v = a2-a1;
                    stack.push(v);
                }
                else if(s.equals("*"))
                {
                    Double a1 = stack.pop();
                    Double a2 = stack.pop();
                    Double v = a2*a1;
                    stack.push(v);
                }
                else if(s.equals("/"))
                {
                    Double a1 = stack.pop();
                    Double a2 = stack.pop();
                    Double v = a2/a1;
                    stack.push(v);
                }
            }
        }
        return stack.pop();
    }
}
Cal.java
package yunsuan;

import java.util.Scanner;

import java.util.*;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner in=new Scanner(System.in);
        Cal cal=new Cal();
        System.out.println("请输入一个计算式:");
        String str=in.next();
        List<String> list=cal.work(str);
        List<String> list2=cal.translate(list);
        /*cal.printList(list);
        System.out.println();
        cal.printList(list2);
        System.out.println();*/
        System.out.println(cal.docal(list2));
        
    }

}
Main.java

结果:

 

 

posted @ 2020-06-07 19:29  MoooJL  阅读(385)  评论(0编辑  收藏  举报