20155227 《Java程序设计》实验五 Java网络编程及安全实验报告

20155227 《Java程序设计》实验五 Java网络编程及安全实验报告

实验内容

任务一:

  • 编写MyBC.java实现中缀表达式转后缀表达式的功能。
  • 编写MyDC.java实现从上面功能中获取的表达式中实现后缀表达式求值的功能。
    我们如何编程实现bc? 把中缀式转化后缀式调用MyDC.java 中的evaluate方法就行了。这样问题转化为如何由中缀式求得后缀式?

中缀式求得后缀式可以使用栈,伪代码如下:

设立一个栈,存放运算符,首先栈为空;
从左到右扫描中缀式,若遇到操作数,直接输出,并输出一个空格作为两个操作数的分隔符;
若遇到运算符,则与栈顶比较,比栈顶级别高则进栈,否则退出栈顶元素并输出,然后输出一个空格作分隔符;
若遇到左括号,进栈;若遇到右括号,则一直退栈输出,直到退到左括号止。
当栈变成空时,输出的结果即为后缀表达式。

MyBC:

import java.util.*;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.Arrays;
public class MyBC {
    private static LinkedList<String> op1 = new LinkedList<>();
    private static LinkedList<String> op2 = new LinkedList<>();
    private static StringBuilder a = new StringBuilder();

    public StringBuilder houzhui(LinkedList<String> list) {
        Iterator<String> i = list.iterator();
        while (i.hasNext()) {
            String s = i.next();
            if (isOperator(s)) {
                if (op1.isEmpty()) {
                    op1.push(s);
                } else {
                    if (priority(op1.peek()) <= priority(s) && !s.equals(")")) {
                        op1.push(s);
                    } else if (!s.equals(")") && priority(op1.peek()) > priority(s)) {
                        while (op1.size() != 0 && priority(op1.peek()) >= priority(s)
                                && !op1.peek().equals("(")) {
                            if (!op1.peek().equals("(")) {
                                String operator = op1.pop();
                                a.append(operator).append(" ");
                                op2.push(operator);
                            }
                        }
                        op1.push(s);
                    } else if (s.equals(")")) {
                        while (!op1.peek().equals("(")) {
                            String operator = op1.pop();
                            a.append(operator).append(" ");
                            op2.push(operator);
                        }
                        op1.pop();
                    }
                }
            } else {
                a.append(s).append(" ");
                op2.push(s);
            }
        }
        if (!op1.isEmpty()) {
            Iterator<String> iterator = op1.iterator();
            while (iterator.hasNext()) {
                String operator = iterator.next();
                a.append(operator).append(" ");
                op2.push(operator);
                iterator.remove();
            }
        }
        return a;
    }

    private static boolean isOperator(String oper) {
        if (oper.equals("+") || oper.equals("-") || oper.equals("/") || oper.equals("*")
                || oper.equals("(") || oper.equals(")")) {
            return true;
        }
        return false;
    }

    private static int priority(String s) {
        switch (s) {
            case "+":
                return 1;
            case "-":
                return 1;
            case "*":
                return 2;
            case "/":
                return 2;
            case "(":
                return 3;
            case ")":
                return 3;
            default:
                return 0;
        }
    }
}

我们如何实现dc?
这要用到栈。对逆波兰式求值时,不需要再考虑运算符的优先级,只需从左到右扫描一遍后缀表达式即可。求值伪代码如下:

设置一个操作数栈,开始栈为空;
从左到右扫描后缀表达式,遇操作数,进栈;

若遇运算符,则从栈中退出两个元素,先退出的放到运算符的右边,后退出的放到运算符左边,运算后的结果再进栈,直到后缀表达式扫描完毕。

此时,栈中仅有一个元素,即为运算的结果。

MyDC:

import java.util.Stack;
import java.util.StringTokenizer;
import java.util.*;



public class MyDC {
    public static int evaluate(StringBuilder b) {
        LinkedList<String> mList = new LinkedList<>();
        String[] postStr = b.toString().split(" ");
        int result;
        for (String s : postStr) {
            if (fuhao(s)) {
                if (!mList.isEmpty()) {
                    int num1 = Integer.valueOf(mList.pop());
                    int num2 = Integer.valueOf(mList.pop());
                    if (s.equals("/") && num1 == 0) {
                        System.out.println("除数不能为0");
                        return 0;
                    }
                    int newNum = cal(num2, num1, s);
                    mList.push(String.valueOf(newNum));
                }
            } else {
                mList.push(s);
            }
        }
        //if (!mList.isEmpty()) {

        //System.out.println("result: "+mList.pop());

        result=Integer.parseInt(mList.pop());
        // }

        return result;
    }

    private static boolean fuhao(String a) {
        if (a.equals("+") || a.equals("-") || a.equals("/") || a.equals("*")
                || a.equals("(") || a.equals(")")) {
            return true;
        }
        return false;
    }
    /*private static int priority(String s) {

        switch (s) {

            case "+":

                return 1;

            case "-":

                return 1;

            case "*":

                return 2;

            case "/":

                return 2;

            case "(":

                return 3;

            case ")":

                return 3;

            default:

                return 0;

        }

    }*/

    private static int cal(int num1, int num2, String operator) {
        switch (operator) {
            case "+":
                return num1 + num2;
            case "-":
                return num1 - num2;
            case "*":
                return num1 * num2;
            case "/":
                return num1 / num2;
            default:
                return 0;
        }
    }
}

    /*private boolean isOperator(String token) {

        return (token.equals("+") || token.equals("-") ||

                token.equals("*") || token.equals("/"));

    }



    private int evalSingleOp(char operation, int op1, int op2) {

        int result = 0;



        switch (operation) {

            case ADD:

                result = op1 + op2;

                break;

            case SUBTRACT:

                result = op1 - op2;

                break;

            case MULTIPLY:

                result = op1 * op2;

                break;

            case DIVIDE:

                result = op1 / op2;

        }



        return result;

    }

}*/

Test:

import java.util.LinkedList;
import java.util.*;

public class Test {
    public static void main(String[] args){
        LinkedList<String> list=new LinkedList<>();
        StringBuilder result1;
        int result2;
        String expression, again;
        System.out.println("请输入一个中缀表达式并以#结束");
        Scanner scanner=new Scanner(System.in);
        String s;
        while (!(s=scanner.next()).equals("#")) {
            list.add(s);
        }
        MyBC hz=new MyBC();
        result1 = hz.houzhui(list);
        System.out.println("后缀表达式: "+result1);
        MyDC evaluator = new MyDC();
        result2 = evaluator.evaluate(result1);
        System.out.println("That expression equals " + result2);
        System.out.println();

    }
}

任务二

  • 结对编程:一人负责客户端,另一人负责服务器
  • 注意责任归宿,要会通过测试证明自己没有问题
  • 基于Java Socket实现客户端/服务器功能,传输方式用TCP
  • 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式通过网络发送给服务器
  • 服务器接收到后缀表达式,调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
  • 客户端显示服务器发送过来的结果

我负责的是服务器部分

任务三

  • 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密后通过网络把密文发送给服务器
  • 服务器接收到后缀表达式表达式后,进行解密(和客户端协商密钥,可以用数组保存),然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
  • 其他要求同任务二

任务四

  • 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
  • 其他要求同任务三

任务五

  • 服务器接收到后缀表达式表达式后,进行解密,解密后计算明文的MD5值,和客户端传来的MD5进行比较,一致则调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
  • 其他要求同任务四

PSP(Personal Software Process)时间

步骤 耗时 百分比
需求分析 20min 12.5%
设计 20min 12.5%
代码实现 80min 50%
测试 20min 12.5%
分析总结 20min 12.5%
posted @ 2017-06-02 12:25  20155227辜彦霖  阅读(197)  评论(0编辑  收藏  举报