java实验一总结

实验一第一部分

在Linux中运行结果

通过cd和mkdir命令建立tree,带包编译并用

javac -d bin

的命令将编译文件保存在bin目录中

通过

java -cp

的命令运行带包的程序

实验第二部分

用idea调试程序
左键点击行号旁边的空白设置断点。

用F7快捷键逐步运行代码

用F9快捷建快速运行到下个断点

右键点击断点可以设置循环条件

实验第三部分

实验题目:实现简单的四则运算
实验代码:

import java.io.*;
import java.util.Stack;

public class siziyunsuan {
    public static void main(String[] args) {
        int i,f;
        double result;
        int zuokuohao1 = 0;
        String ch2 = new String();
        BufferedReader buf = new BufferedReader (new InputStreamReader(System.in));
        try{
            String str = buf.readLine();
            f = chu0.chu0(str);
            if(f == 0) {
                char[] ch1 = str.toCharArray();
                int len1 = ch1.length;
                Stack<Character> operators = new Stack<>();
                Stack output = new Stack<>();
                zuokuohao1 = rpn(operators, output, str);
                for (i = 0; i < len1 - 2 * zuokuohao1; i++) {
                    ch2 = output.pop() + ch2;
                }
                System.out.println(ch2);
                result = jisuanhouxu.evaluate(ch2);
                System.out.println(result);
            }
            else{
                System.out.println("除数为0");
            }


        }catch(IOException e){

        }



    }
    public static int rpn(Stack<Character> operators, Stack output, String str) {
        char[] chars = str.toCharArray();
        int pre = 0;
        boolean digital;
        int zuokuohao = 0;
        int len = chars.length;
        int bracket = 0;
        for (int i = 0; i < len; ) {
            pre = i;
            digital = Boolean.FALSE;
            while (i < len && !Operator.isOperator(chars[i])) {
                i++;
                digital = Boolean.TRUE;
            }
            if (digital) {
                output.push(str.substring(pre, i));
            } else {
                char o = chars[i++];
                if (o == '(') {
                    bracket++;
                    zuokuohao++;
                }
                if (bracket > 0) {
                    if (o == ')') {
                        while (!operators.empty()) {
                            char top = operators.pop();
                            if (top == '(') {
                                break;
                            }
                            output.push(top);
                        }
                        bracket--;
                    } else {
                        while (!operators.empty() && operators.peek() != '(' && Operator.cmp(o, operators.peek()) <= 0) {
                            output.push(operators.pop());
                        }
                        operators.push(o);
                    }
                } else {
                    while (!operators.empty() && Operator.cmp(o, operators.peek()) <= 0) {
                        output.push(operators.pop());
                    }
                    operators.push(o);
                }
            }
        }
        while (!operators.empty()) {
            output.push(operators.pop());
        }
        return zuokuohao;
    }
}
enum Operator {
    ADD('+', 1), SUBTRACT('-', 1),
    MULTIPLY('*', 2), DIVIDE('/', 2),
    LEFT_BRACKET('(', 3), RIGHT_BRACKET(')', 3);
    char value;
    int priority;
    Operator(char value, int priority) {
        this.value = value;
        this.priority = priority;
    }
    public static int cmp(char c1, char c2) {
        int p1 = 0;
        int p2 = 0;
        for (Operator o : Operator.values()) {
            if (o.value == c1) {
                p1 = o.priority;
            }
            if (o.value == c2) {
                p2 = o.priority;
            }
        }
        return p1 - p2;
    }
    public static boolean isOperator(char c) {
        for (Operator o : Operator.values()) {
            if (o.value == c) {
                return true;
            }
        }
        return false;
    }
}
 class jisuanhouxu {
    public static double evaluate(String s) {
        double c1 = 0;
        double c2 = 0;
        double d1 = 0;
        double d2 = 0;
        char[] ch = s.toCharArray();
        Stack<Double> num = new Stack<>();
        for (int i = 0; i < ch.length; i++) {
            char c = ch[i];
            if (c >= '0' && c <= '9') {
                num.push(Double.parseDouble(Character.toString(c)));
            } else {
                switch (c) {
                    case '+':
                        num.push(num.pop() + num.pop());
                        break;
                    case '-':
                        c1 = num.pop();
                        c2 = num.pop();
                        num.push(c2 - c1);
                        break;
                    case '*':
                        num.push(num.pop() * num.pop());
                        break;
                    case '/':
                        d1 = num.pop();
                        d2 = num.pop();
                        num.push(d2 / d1);
                        break;
                    default:
                        break;
                }
            }
        }
        return num.pop();
    }
}
class chu0{
    public static int chu0(String s){
        int i;
        int flag = 0;
        char[] ch = s.toCharArray();
        for(i=0;i < ch.length;i++){
            if(ch[i] == '/' && ch[i+1] == '0')
                flag = 1;
        }
        return flag;
    }

}

实验运行结果

实验中遇到的问题

1、首先是读题问题。题目的要求应是键盘输出式子,而不是随机生成式子。随机生成式子的代码我写了两天,浪费了许多时间,但也不是没有什么收获。随机生成式子的难点在于括号的插入,我一开始的想法是先生成不带括号的式子,然后将括号插入其中。后面发现这样实现起来需要考虑的地方太多。要考虑括号中间不能为空或者只有一个数,还有保证左右括号的数量相等,还有考虑多个左括号或右括号在一起的情况等等。于是我想能否在生成式子的过程中就插入括号呢?后来我还真找到一种方法,那就是通过对str = str1 + op + str2这个函数的递归生成式子,并在每次递归时通过概率判断是否在str1或str2或str1 + op + str2的两端通过拼接生成括号,这种方法生成括号不用考虑任何问题,生成带括号的式子也不会有任何的数学语法错误(因不是实验要求,没有在代码中展现)。
2、第二个难点就是编写逆波兰法。其中有两个较难的地方。(1)是如何控制例如100这样的多位数不被看成1,0,0三个元素。我通过双计数的方式来解决,也就是i跟pre两个变量计数,当循环遍历到数字时,pre指向100中的1,i通过i++的方式循环到100中末位的0,使用String类里的方法substring(pre, i)将1,0,0看作100输出。第二个难点就在于栈里的数据已经按后序排好(假设是32),可由于栈是先进后出,读出来的结果会是23,所以我想到了用字符串向前拼接的方式ch2 = output.pop() + ch2;就能输出32*。
3、第三个问题是在多次运行程序时有时候值会出现 infinity,后经过调试发现是没有考虑到除0的特殊情况,于是我通过编写chu0类,并在chu0中编写静态方法能够判断是否有除0的情况并通过返回flag的值控制程序。
4、最后一个就是时间的安排问题。我提前三天开始写实验,本以为足够完成实验,可没有想到出现读题错误的特殊情况,让前两天的工作覆水东流,最后只剩一天的时间编写实验程序导致不能按时完成。所以以后对于较大任务量的作业,一定要尽早安排时间完成,防止突发情况的发生。

posted @ 2019-04-05 22:55  PwnKi  阅读(1627)  评论(0编辑  收藏  举报