四则运算之结对作业

目录

 

一、背景

二、功能展示

三、代码展示

四、总结


一、背景

(在这里,我附上我的队友的博客链接:https://blog.csdn.net/MissQnamesXu/article/details/89305402)

上周,老师在之前四则运算作业的基础上,又布置下了结对作业,即两人组队,完成一个完整的四则运算的项目。由于我是工作室后端的成员,于是,我便担任起了后端的任务。

我们先分析了老师提出的需求。老师提出的需求有一下几点:

  1. 定制出题要求每次出题时用户都可以在界面上定制如下参数:题目数量,算式数值范围(仅包括原始题目与最终结果的绝对值的数值范围),题目中最多有多少个运算符,题目中是否包含乘除法,题目中是否包含括号。在点击相应出题按钮后将生成题目文件(不包含答案)。
  2. 做题功能。出题后,用户可以开始答题
  3. 判题功能。用户答题过程中或者全部完成后可以判断对错,并统计分数和时间。
  4. 本次界面可以用网页版或客户端任何一种形式完成。

我分析了老师提出的需求,再结合了我第一次写的函数,认为只需要改动一些小小的地方,就可以完成老师的要求。

这次作业,我用了当下web开发中最流行的一个框架——springboot,这让我真正的体验到了springboot的便捷之处,不用再配一堆xml文件,也不用配tomcat,真的是太方便了!

二、功能展示

本小组完成了老师要求的任务,并且,又新增了文件下载的功能,用户可以自由选择是否下载题目。

 

 

文件下载到浏览器默认的下载路径

三、代码展示

这是我的项目目录

后端代码主要分为三块:

1、entity

主要用来传JSON数组

2、Servicce

Service又分为service和impl两大部分,service用来放接口,而impl用来放最底层的代码,也就是最核心的算法部分

(1)接口部分

package com.example.demo.service;

public interface QuestionService {

    public int algorithm(String s);


    public int calculate(int a, int b, String stmp);

    public int[] index(int n, int m);

    public String[] create(int max, int min, int maxOper,  int isBrac, int isMul);

    //用来测试的方法
    //public String[] create();
}

(2)核心算法

我的核心算法和我第一次的作业并没有做太大的改动,只修改了一些细节部分。

首先是逆波兰表达式

public int algorithm(String s) {
        //放数字
        Stack<Integer> stack1 = new Stack<>();
        //放操作符
        Stack<String> stack2 = new Stack<>();
        //存放运算符优先级
        HashMap<String, Integer> hashmap = new HashMap<>();
        hashmap.put("(", 0);
        hashmap.put("+", 1);
        hashmap.put("-", 1);
        hashmap.put("*", 2);
        hashmap.put("÷", 2);

        for (int i = 0; i < s.length();) {
            //设置可变长的字符串
            StringBuffer digit = new StringBuffer();
            //将式子字符串切割为c字符
            char c = s.charAt(i);
            //判断字符是否为10进制数字,将一个数加入digit
            while (Character.isDigit(c)) {
                digit.append(c);
                i++;
                c = s.charAt(i);
            }
            //当前digit里面已经无数字,即当前处理符号
            if (digit.length() == 0){
                switch (c) {
                    case '(': {
                        stack2.push(String.valueOf(c));
                        break;
                    }
                    //遇到右括号了计算,因为(的优先级最高
                    case ')': {
                        String stmp = stack2.pop();
                        while (!stack2.isEmpty() && !stmp.equals("(")) {
                            int a = stack1.pop();
                            int b = stack1.pop();
                            int sresulat = calculate(b, a, stmp);
                            if(sresulat<0)
                                return  -1;
                            stack1.push(sresulat);
                            //符号指向下一个计算符号
                            stmp = stack2.pop();
                        }
                        break;
                    }
                    case '=': {
                        String stmp;
                        while (!stack2.isEmpty()) {
                            stmp = stack2.pop();
                            int a = stack1.pop();
                            int b = stack1.pop();
                            int sresulat = calculate(b, a, stmp);
                            if(sresulat<0)
                                return  -1;
                            stack1.push(sresulat);
                        }
                        break;
                    }
                    default: {
                        String stmp;
                        while (!stack2.isEmpty()) {
                            stmp = stack2.pop();
                            //比较优先级
                            if (hashmap.get(stmp) >= hashmap.get(String.valueOf(c))) {
                                int a = stack1.pop();
                                int b = stack1.pop();
                                int sresulat =calculate (b, a, stmp);
                                if(sresulat<0)
                                    return  -1;
                                stack1.push(sresulat);
                            }
                            else {
                                stack2.push(stmp);
                                break;
                            }
                        }
                        //将符号压入符号栈
                        stack2.push(String.valueOf(c));
                        break;
                    }
                }
            }
            else {
                //处理数字
                stack1.push(Integer.valueOf(digit.toString()));
                continue;
            }
            i++;
        }
        //返回栈底得到答案
        return stack1.peek();
    }

接下来是生成表达式的函数

public String[] create(int max, int min, int maxOper,  int isBrac, int isMul){
//        int max=10 ;
//        int min=0 ;
//        int maxOper=5;
//        int isBrac=1;
//        int isMul=4;
        String[] string = new String[2];
        Random r = new Random();
        String[] opertor = {"+","-","*","÷"};
        //操作符的个数
        int operatorNum = maxOper;
        //新建数组来保存操作数
        int[] number = new  int[operatorNum+1];
        //操作符的下标,若isMul等于2,则没有乘除法,若isMul等于4,则含有乘除法
        int[] arr = index(operatorNum, isMul);
        String s = new String();

        for(int j=0;j<operatorNum+1;j++){
            number[j] = min + r.nextInt(max-min);
        }

        //如果flag=0,则该式子加括号,如果flag=1,则该式子不加括号(自己设定)

        switch (operatorNum){
            case 3:{
                if(isBrac == 0){
                    s = "(" + number[0] + opertor[arr[0]] + number[1] + ")" +opertor[arr[1]]+ "(" + number[2] + opertor[arr[2]] + number[3] + ")";
                }
                else{
                    s = number[0] + opertor[arr[0]] + number[1]+opertor[arr[1]]+number[2] + opertor[arr[2]] + number[3] ;
                }
                break;
            }
            case 4:{
                if(isBrac ==0){
                    s = "(" + "(" + number[0] + opertor[arr[0]] + number[1] + ")" + opertor[arr[1]] + number[2] + ")" + opertor[arr[2]] + "(" + number[3] + opertor[arr[3]] + number[4] + ")";
                }
                else{
                    s = number[0] + opertor[arr[0]] + number[1] +opertor[arr[1]] + number[2] + opertor[arr[2]] + number[3] + opertor[arr[3]] + number[4] ;
                }
                break;
            }
            case 5:{
                if(isBrac ==0){
                    s = "(" + "(" + number[0] + opertor[arr[0]]+number[1]+")" + opertor[arr[1]] + number[2] + ")" +opertor[arr[2]]+ "(" + "(" + number[3] + opertor[arr[3]] + number[4] + ")" + opertor[arr[4]] + number[5] + ")";
                }
                else{
                    s = number[0] + opertor[arr[0]]+number[1]+ opertor[arr[1]] + number[2] +opertor[arr[2]] + number[3] + opertor[arr[3]] + number[4] + opertor[arr[4]] + number[5] ;
                }
                break;
            }
        }
        s+="=";
        int answer = algorithm(s);

        //判断式子是否符合要求,凡是返回负数的就是不合格的
        if(answer>min && answer<max){
            string[0] = s;
            string[1] = String.valueOf(answer);
            return string;

        }else{
            return create(max, min, maxOper, isBrac, isMul);
        }
    }

这两个函数是最重要的两个函数了,其他的函数就不做展示了,可以到我的代码仓库中去看完整的代码

3、Controller

主要用来放和前端进行交互的代码

我一共写了两个controller,一个是createFile,另一个是downloadFile

createFile用来在本地生成文件,即生成在本地目录下,另一个用来下载文件,从本地读取文件然后在页面下载

我在与前端传值的时候用到了阿里开发的fastjson方法,将式子和答案分别转成json对象,然后存入json数组传给前端;在接受前端传来的数据时,我用到了框架中的@RequestParam注解接受前端的传来的值。

@RequestMapping("/create")
    public String creatFile(@RequestParam("num") int n,  @RequestParam("max") int max, @RequestParam("min") int min, @RequestParam("maxOper") int maxOper, @RequestParam("isBrac") int isBrac, @RequestParam("isMul") int isMul)throws IOException{
        File file = new File("../result.txt");
        if (file.exists()) { //如果文件已存在,则删除文件
            file.delete();
        }
        JSONArray jsonArray = new JSONArray();
        if(file.createNewFile()){

            FileOutputStream txtfile = new FileOutputStream(file);
            PrintStream p = new PrintStream(txtfile);
//                p.println("2017012842");
            for(int i=0;i<10;i++){
                String[] s =  questionService.create(max, min, maxOper,  isBrac, isMul);
                //将式子和答案分开
                String que = s[0];
                String answer = s[1];
                //用阿里巴巴开发的fastjson将式子和答案分别转成JSON,传给前端
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("QUESTION", que);
                jsonObject.put("ANSWER", answer);
                jsonArray.add(jsonObject);
                p.print(que);
                p.println(answer);
            }
            txtfile.close();
            p.close();
            System.out.println("文件创建成功!");
        }
        return jsonArray.toJSONString();
    }
@RequestMapping("/downloadFile")
    public String downloadFile(HttpServletRequest request, HttpServletResponse response) {
        String fileName = "result.txt";
        if (fileName != null) {
            String realPath = "D:\\nenuscfx";
            File file = new File(realPath, fileName);
            if (file.exists()) {
                response.setContentType("application/force-download");// 设置强制下载不打开
                response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 设置文件名
                byte[] buffer = new byte[1024];
                FileInputStream fis = null;
                BufferedInputStream bis = null;
                try {
                    fis = new FileInputStream(file);
                    bis = new BufferedInputStream(fis);
                    OutputStream os = response.getOutputStream();
                    int i = bis.read(buffer);
                    while (i != -1) {
                        os.write(buffer, 0, i);
                        i = bis.read(buffer);
                    }
                    System.out.println("success");
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (bis != null) {
                        try {
                            bis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fis != null) {
                        try {
                            fis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        return null;
    }

四、总结

         这次作业让我收获良多。在这次作业之前,我虽说自己学习了springboot,但还是对其没有很清楚的了解,但通过这次作业,让我熟悉了springboot,终于感觉自己跟上了时代的潮流^-^。

       不仅如此,此次作业,由于前端采用了vue框架,后端采用了springboot框架,因此,在前后端合代码时,不需要用到JSP,而是后端只需给前端一个接口即可完成项目的合并,这大大省却了工程量。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值