第二次作业

GitHub地址

https://github.com/onecatzyg/sizeyunsuan

PSP

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 20 30
· Estimate · 估计这个任务需要多少时间 20 30
Development 开发 1080 1410
· Analysis · 需求分析 (包括学习新技术) 40 120
· Design Spec · 生成设计文档 40 40
· Design Review · 设计复审 (和同事审核设计文档) 20 20
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 20 10
· Design · 具体设计 60 60
· Coding · 具体编码 800 1080
· Code Review · 代码复审 60 60
· Test · 测试(自我测试,修改代码,提交修改) 40 120
Reporting 报告 120 120
· Test Report · 测试报告 50 50
· Size Measurement · 计算工作量 20 20
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 50 50
合计   1320 1560

解题思路

       刚开始拿到题目之后想的是将操作符存于数组中,然后利用随机生成数的值除以4取余来确定运算符,但是在动手真正写代码的过程中却发现没那么简单,自己的基础很差,以前学的数据结构中的一些东西都忘了,虽然知道可以将运算式变换为后缀表达式然后进行运算,但是实际操作却感觉无从下手,根本不知道该怎么写。后来迫不得已只能,在以确定运算符个数为3的前提下,将所有的运算符的可能性一一枚举出来,运算符的种类有{“+”,“-”,“*”,“/”}这4种,4³=64种,然后利用0~63的随机生成数来确定运算符的组合,写了大概半天(大概是因为心不在焉,注意力不集中),写到后来发现问题有些严重,如果根据这种类似于枚举法的暴力方法来一直写下去的话,再加上运算数可能为分数,这样整个运算式的种数远远不是64种写的完的,而是4³x(2^4)=1024!!!!这样写下去的话,代码行数完完全全超出预期,可能需要上万行代码,所以后来坚持不下去了(舍友也说这样写可能会被老师骂死),放弃了这种死脑筋的方法。

       然后开始看中缀表达式到后缀表达式的转换,看了大概两个小时,弄懂了怎么回事,想起了以前学的一些东西,但是代码还是写不出来(自我反省:动手能力极差!!),然后开始上网找大牛们的写法,然后找到了一位大牛的写法,http://blog.csdn.net/njr465167967/article/details/51969439,中间他虽然有个别文字错误,但是还是可以比较好的理解(主要是他的代码比较全),写出了整个过程,中间好多地方作为不熟悉java语言编程的我看得有点难受,但好在还是熬过来了,看懂了他的想法和其中代码操作,我大部分的关键代码是直接用他的(自己写的有点问题,然后时间来不及了,索性先用他的,然后下来自己再尝试一下)。但是有一个问题我还是没有解决,就是真分数的运算,在java中没有像python中那样的分数运算的包,自己还没有完成,只完成了整数的运算。

设计实现过程

      两个类:houzhuiyunsuan.class和transf.class

      transf.class中主要是后缀表达式的运算其中包含processInfix、isDigital判断是否为数字、process()转化过程、getParent()匹配、getOperation(String str, int priority)操作函数、getPriority(String str)、getPost()去掉字符串首位空格等

      houzhuiyunsuan.class中compute(String str)四则运算的操作

     

代码说明

由后缀表达式得到四则运算结果的实现过程:

    public void operate(){

       String[] strArr = post.split(" ");

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

           String temp = strArr[i];

           if(isDigital(temp)){

               stack.push(Integer.valueOf(temp));

           }else{

               int result = compute(temp);

               stack.push(result);

           }

       }

   }

四则运算操作 :

private int compute(String str){

       int re = 0;

       int m = stack.pop();//出栈第一个元素

       int n = stack.pop();//出栈第二个元素

       switch(str){

       case "+" :

           re = n + m;

           break;

       case "-" :

           re = n - m;

           break;

       case "*" :

           re = n * m;

           break;

       case "/" :

           re = n / m;

           break;

       default :

           break;

       }

       return re;

   }

//判断是否为数字

 private boolean isDigital(String str){

       char[] chArr = str.toCharArray();

       int len = chArr.length;

       int count = 0;

       for(int i = 0; i < len; i++){

           if(chArr[i] >= '0' && chArr[i] <= '9')

               count++;

       }

       return count == len;

   }

运算式转化为后缀表达式:

private String processInfix(String infix) {

        String result = "";

        for (int i = 0; i < infix.length() - 1; i++) {

            char temp1 = infix.charAt(i);

            char temp2 = infix.charAt(i + 1);

            if (isDigital(temp1) && isDigital(temp2)) {

                result += temp1;

            } else {

                result += temp1 + " ";

            }

        }

        result += infix.charAt(infix.length() - 1); // 将最后一个元素添加进去

        return result;

    }

 public void process() {//转化过程

        String[] strArr = processInfix(infix).split(" ");

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

            String str = strArr[i];

            switch (str) {//运算符操作

            case "+":

            case "-":

                getOperation(str, 1);

                break;

            case "*":

            case "/":

                getOperation(str, 2);

                break;

            case "(":

                stack.push(str);

                break;

            case ")":

                getParent();

                break;

            default:

                post += " " + str;

                break;

            }

        }

        while (!stack.isEmpty()) {//当栈非空则在原有字符串后加上出栈元素

            post += " " + stack.pop();

        }

    }

    private void getParent() {

        while (!stack.isEmpty()) {

            String top = stack.pop();

            if (top.equals("(")) {

                break;

            } else {

                post += " " + top;

            }

        }

    }

    private void getOperation(String str, int priority) {

        while (!stack.isEmpty()) {

            String top = stack.pop();

            if (top.equals("(")) {

                stack.push(top);

                break;

            } else {

                int priTop = getPriority(top);

                if (priTop < priority) {

                    stack.push(top);

                    break;

                } else {

                    post += " " + top;

                }

            }

        }

        stack.push(str);

    }

    private int getPriority(String str) {

        int pri = 0;

        if (str.equals("+") || str.equals("-")) {

            pri = 1;

        } else {

            pri = 2;

        }

        return pri;

    }

 

    public String getPost() {

        return post.trim();//去掉字符串首位空格

    }

测试说明

     

测试过程中发现还是有些问题,式子算出来的都是整数,没有考虑到分数的情况,有括号的情况也没有考虑到。作业提交之后再找时间改进吧。

项目小结

在实现的过程中,动手能力太重要了,以后要多加练习,自己的能力真的很差,在老师看来很简单的东西,但是对于自己来讲是个不小的挑战。数字和字符的处理看起来简单,但是做起来真的有点难。

 

 

 

posted on 2017-09-27 21:24  一只猫、  阅读(260)  评论(2编辑  收藏  举报

导航