Java教程

湖南大学结队编程项目队友代码互评

本文主要是介绍湖南大学结队编程项目队友代码互评,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一.简介

本篇博客为对结对编程搭档李津松的个人项目(中小学数学卷子自动生成程序)的评价。该代码使用语言为c++。本次点评仅为个人观点,如有错误,请多指正!

二.代码评析

/*
  copyright jinsong li 2021/9/26
*/
#include <direct.h>
#include <time.h>
#include <string.h>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <fstream>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::to_string;
using std::vector;
using std::ifstream;
using std::ofstream;
void getFiles(string path, vector<string> &files) {
  // 文件句
  int16_t hFile = 0;
  // 文件信息
  struct _finddata_t fileinfo;
  string pathName;
  if ((hFile = _findfirst(pathName.assign(path).c_str(), &fileinfo)) != -1) {
    do {
        if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
          files.push_back(pathName.assign(path).
                          append("/").append(fileinfo.name));
    } while (_findnext(hFile, &fileinfo) == 0);
    _findclose(hFile);
  }
}
// 查重函数:将先前的文档进行遍历,
// 然后在提取出每一行的字符串,
// 比较每一行的字符串,
// 若没有重复则返回1,重复了就返回-1
int find(string test, int ty) {
  string FindType = "";
  switch (ty) {
    case 1: {
      FindType = "./张三1/";
      break;
    }
    case 2: {
      FindType = "./张三2/";
      break;
    }
    case 3: {
      FindType = "./张三3/";
      break;
    }
    case 4: {
      FindType = "./李四1/";
      break;
    }
    case 5: {
      FindType = "./李四2/";
      break;
    }
    case 6: {
      FindType = "./李四3/";
      break;
    }
    case 7: {
      FindType = "./王五1/";
      break;
    }
    case 8: {
      FindType = "./王五2/";
      break;
    }
    case 9: {
      FindType = "./王五3/";
      break;
    }
  }
  vector<string> files;
  getFiles(FindType, files);
  int size = files.size();
  for (int i = 0; i < size; i++) {
    ifstream fin(files[i]);
    string past;
    while (fin >> past) {
      if (past == test)
        return (-1);
    }
  }
  return 1;
}

// 试卷生成函数:通过随机数生成不同操作数,
// 根据引用的不同类型的试卷,
// 生成不同的试卷并保存在相应的位置。
void get(int NUM, int USER, int TYPE) {
  time_t t = time(NULL);
  ofstream File;
  char ttime[33];
  // 确定用户
  switch (USER) {
    case 1: {
      strftime(ttime, 33, "./张三1/%Y-%m-%d-%H-%M-%S.txt", localtime(&t));
      break;
    }
    case 2: {
      strftime(ttime, 33, "./张三2/%Y-%m-%d-%H-%M-%S.txt", localtime(&t));
      break;
    }
    case 3: {
      strftime(ttime, 33, "./张三3/%Y-%m-%d-%H-%M-%S.txt", localtime(&t));
      break;
    }
    case 4: {
      strftime(ttime, 33, "./李四1/%Y-%m-%d-%H-%M-%S.txt", localtime(&t));
      break;
    }
    case 5: {
      strftime(ttime, 33, "./李四2/%Y-%m-%d-%H-%M-%S.txt", localtime(&t));
      break;
    }
    case 6: {
      strftime(ttime, 33, "./李四3/%Y-%m-%d-%H-%M-%S.txt", localtime(&t));
      break;
    }
    case 7: {
      strftime(ttime, 33, "./王五1/%Y-%m-%d-%H-%M-%S.txt", localtime(&t));
      break;
    }
    case 8: {
      strftime(ttime, 33, "./王五2/%Y-%m-%d-%H-%M-%S.txt", localtime(&t));
      break;
    }
    case 9: {
      strftime(ttime, 33, "./王五3/%Y-%m-%d-%H-%M-%S.txt", localtime(&t));
      break;
    }
  }
  File.open(ttime);
  int randNum = 0;
  int diff = 0;
  // 确定类型
  switch (TYPE) {
    case 1: {
      diff = 0;
      break;
    }
    case 2: {
      diff = 2;
      break;
    }
    case 3: {
      diff = 5;
      break;
    }
  }
  int syn = 0, spin = 0;
  // 生成题目
  for (int i = 1; i <= NUM; i++) {
    File << i << ". " << endl;
    if (diff == 0) {
      randNum = rand() % 4 + 2;
    } else {
      randNum = rand() % 5 + 1;
    }
    int Number[randNum] = {0, 0, 0, 0, 0};
    string sNumber[randNum] = {"", "", "", "", ""};
    for (int j = 0; j < randNum; j++) {
      Number[j] = rand() % 100 + 1;
      sNumber[j] = to_string(Number[j]);
    }
    string FileWrite = "";
    if (diff == 0) {
      spin = 0;
    } else if (diff == 2) {
      spin = rand() % 2 + 1;
    } else if (diff == 5) {
      spin = rand() % 3 + 3;
    }
    string spis = "";
    switch (spin) {
      case 0: {
        FileWrite = FileWrite + sNumber[0];
        break;
      }
      case 1: {
        spis = spis + "^2";
        FileWrite = FileWrite + sNumber[0];
        FileWrite = FileWrite + spis;
        break;
      }
      case 2: {
        spis = spis + "√";
        FileWrite = FileWrite + spis;
        FileWrite = FileWrite + sNumber[0];
        break;
      }
      case 3: {
        spis = spis + "sin";
        FileWrite = FileWrite + spis;
        FileWrite = FileWrite + sNumber[0];
        break;
      }
      case 4: {
        spis = spis + "cos";
        FileWrite = FileWrite + spis;
        FileWrite = FileWrite + sNumber[0];
        break;
      }
      case 5: {
        spis = spis + "tan";
        FileWrite = FileWrite + spis;
        FileWrite = FileWrite + sNumber[0];
        break;
      }
    }
    if (randNum != 1) {
      int flag = 0;
      int dir = 0;
      for (int j = 1; j < randNum; j++) {
        syn = rand() % 4;
        string symbol = "";
        switch (syn) {
          case 0: {
            symbol = symbol + '+';
            break;
          }
          case 1: {
            symbol = symbol + '-';
            break;
          }
          case 2: {
            symbol = symbol + '*';
            break;
          }
          case 3: {
            symbol = symbol + '/';
            break;
          }
        }
        FileWrite = FileWrite + symbol;
        if ((rand() % 3 == 1) &&
            (flag == 0) &&
            (j != randNum - 1)) {
          FileWrite = FileWrite + "(";
          flag = 1;
          dir = j;
        }
        FileWrite = FileWrite + sNumber[j];
        if ((dir != j) &&
            (flag == 1) &&
            (rand() % 3 == 2)) {
          FileWrite = FileWrite + ")";
          flag = 2;
        }
      }
      if (flag == 1) {
        FileWrite = FileWrite + ")";
        flag = 2;
      }
    }
    if (find(FileWrite, USER) == 1) {
      File << FileWrite;
      File << endl << endl;
    } else {
      i = i - 1;
    }
  }
  File.close();
}
int user = 0;
int type = 0;
// 主函数
int main() {
  cout << "试卷生成系统" << endl;
  cout << "请输入用户名和密码" << endl;
  while (1) {
    // user等于0时表示登录初始界面,不同的user的值表示不同的账户
    if (user == 0) {
      char username[20] = "";
      char password[20] = "";
      cin >> username >> password;
      if ((strcmp(username, "张三1") == 0) &&
          (strcmp(password, "123") == 0)) {
        cout << "登录成功" << endl;
        cout << "当前选择为小学出题" << endl;
        user = 1;
        type = 1;
      } else if ((strcmp(username, "张三2") == 0) &&
                 (strcmp(password, "123") == 0)) {
        cout << "登录成功" << endl;
        cout << "当前选择为小学出题" << endl;
        user = 2;
        type = 1;
      } else if ((strcmp(username, "张三3") == 0) &&
                 (strcmp(password, "123") == 0)) {
        cout << "登录成功" << endl;
        cout << "当前选择为小学出题" << endl;
        user = 3;
        type = 1;
      } else if ((strcmp(username, "李四1") == 0) &&
                 (strcmp(password, "123") == 0)) {
        cout << "登录成功" << endl;
        cout << "当前选择为初中出题" << endl;
        user = 4;
        type = 2;
      } else if ((strcmp(username, "李四2") == 0) &&
                 (strcmp(password, "123") == 0)) {
        cout << "登录成功" << endl;
        cout << "当前选择为初中出题" << endl;
        user = 5;
        type = 2;
      } else if ((strcmp(username, "李四3") == 0) &&
                 (strcmp(password, "123") == 0)) {
        cout << "登录成功" << endl;
        cout << "当前选择为初中出题" << endl;
        user = 6;
        type = 2;
      } else if ((strcmp(username, "王五1") == 0) &&
                 (strcmp(password, "123") == 0)) {
        cout << "登录成功" << endl;
        cout << "当前选择为高中出题" << endl;
        user = 7;
        type = 3;
      } else if ((strcmp(username, "王五2") == 0) &&
                 (strcmp(password, "123") == 0)) {
        cout << "登录成功" << endl;
        cout << "当前选择为高中出题" << endl;
        user = 8;
        type = 3;
      } else if ((strcmp(username, "王五3") == 0) &&
                 (strcmp(password, "123") == 0)) {
        cout << "登录成功" << endl;
        cout << "当前选择为高中出题" << endl;
        user = 9;
        type = 3;
      } else {
        cout << "请输入正确的用户名、密码:" << endl;
      }
    }
    // user大于等于1时进入生成试卷系统
    if (user >= 1) {
      char choosetype[20] = "";
      cout << "是否更换当前出题类型" << endl;
      cin >> choosetype;
      // 切换出题类型
      if (strcmp(choosetype, "切换为小学") == 0) {
        type = 1;
      } else if (strcmp(choosetype, "切换为初中") == 0) {
        type = 2;
      } else if (strcmp(choosetype, "切换为高中") == 0) {
        type = 3;
      } else {
        cout << "请输入小学、初中和高中三个选项中的一个" << endl;
        continue;
      }
      switch (type) {
        case 1: {
          cout << "准备生成小学数学题目,请输入生成题目数量";
          cout << "(输入-1将退出当前用户,重新登录):" << endl;
          break;
        }
        case 2: {
          cout << "准备生成初中数学题目,请输入生成题目数量";
          cout << "(输入-1将退出当前用户,重新登录):" << endl;
          break;
        }
        case 3: {
          cout << "准备生成高中数学题目,请输入生成题目数量";
          cout << "(输入-1将退出当前用户,重新登录):" << endl;
          break;
        }
      }
      int number = 0;
      cin >> number;
      // 选择出题数量
      if (number == -1) {
        user = 0;
      } else if ((number <= 30) &&
                 (number >= 10)) {
        // 调用生成试卷函数:将试题数量、用户、类型传入
        get(number, user, type);
        cout << "卷子生成成功!已退出" << endl;
        cout << "试卷生成系统" << endl;
        cout << "请输入用户名和密码" << endl;
        user = 0;
      }
    }
  }
}
View Code

本次代码使用将近400行代码来实现出卷功能。我将以登录,切换出卷模式,出卷,查重这四个功能进行讲述。

(1)登录功能

使用while循环用if来判断用户及密码是否正确,并设定了用户类型跟出卷类型为user跟type。

cout << "试卷生成系统" << endl;
  cout << "请输入用户名和密码" << endl;
  while (1) {
    // user等于0时表示登录初始界面,不同的user的值表示不同的账户
    if (user == 0) {
      char username[20] = "";
      char password[20] = "";
      cin >> username >> password;
      if ((strcmp(username, "张三1") == 0) &&
          (strcmp(password, "123") == 0)) {
        cout << "登录成功" << endl;
        cout << "当前选择为小学出题" << endl;
        user = 1;
        type = 1;
      } else if ((strcmp(username, "张三2") == 0) &&
                 (strcmp(password, "123") == 0)) {
        cout << "登录成功" << endl;
        cout << "当前选择为小学出题" << endl;
        user = 2;
        type = 1;
      } else if ((strcmp(username, "张三3") == 0) &&
                 (strcmp(password, "123") == 0)) {
        cout << "登录成功" << endl;
        cout << "当前选择为小学出题" << endl;
        user = 3;
        type = 1;
      } else if ((strcmp(username, "李四1") == 0) &&
                 (strcmp(password, "123") == 0)) {
        cout << "登录成功" << endl;
        cout << "当前选择为初中出题" << endl;
        user = 4;
        type = 2;
      } else if ((strcmp(username, "李四2") == 0) &&
                 (strcmp(password, "123") == 0)) {
        cout << "登录成功" << endl;
        cout << "当前选择为初中出题" << endl;
        user = 5;
        type = 2;
      } else if ((strcmp(username, "李四3") == 0) &&
                 (strcmp(password, "123") == 0)) {
        cout << "登录成功" << endl;
        cout << "当前选择为初中出题" << endl;
        user = 6;
        type = 2;
      } else if ((strcmp(username, "王五1") == 0) &&
                 (strcmp(password, "123") == 0)) {
        cout << "登录成功" << endl;
        cout << "当前选择为高中出题" << endl;
        user = 7;
        type = 3;
      } else if ((strcmp(username, "王五2") == 0) &&
                 (strcmp(password, "123") == 0)) {
        cout << "登录成功" << endl;
        cout << "当前选择为高中出题" << endl;
        user = 8;
        type = 3;
      } else if ((strcmp(username, "王五3") == 0) &&
                 (strcmp(password, "123") == 0)) {
        cout << "登录成功" << endl;
        cout << "当前选择为高中出题" << endl;
        user = 9;
        type = 3;
      } else {
        cout << "请输入正确的用户名、密码:" << endl;
      }
    }
登录代码

 

 

 

 (2)切换出卷类型

在每次出卷前都要输入出卷的类型如”切换为小学“才能进入出卷,并输出当时为什么类型的出卷。

 if (user >= 1) {
      char choosetype[20] = "";
      cout << "是否更换当前出题类型" << endl;
      cin >> choosetype;
      // 切换出题类型
      if (strcmp(choosetype, "切换为小学") == 0) {
        type = 1;
      } else if (strcmp(choosetype, "切换为初中") == 0) {
        type = 2;
      } else if (strcmp(choosetype, "切换为高中") == 0) {
        type = 3;
      } else {
        cout << "请输入小学、初中和高中三个选项中的一个" << endl;
        continue;
      }
      switch (type) {
        case 1: {
          cout << "准备生成小学数学题目,请输入生成题目数量";
          cout << "(输入-1将退出当前用户,重新登录):" << endl;
          break;
        }
        case 2: {
          cout << "准备生成初中数学题目,请输入生成题目数量";
          cout << "(输入-1将退出当前用户,重新登录):" << endl;
          break;
        }
        case 3: {
          cout << "准备生成高中数学题目,请输入生成题目数量";
          cout << "(输入-1将退出当前用户,重新登录):" << endl;
          break;
        }
      }
切换出卷类型代码

(3)出卷

使用get(int NUM, int USER, int TYPE)来进行出卷,传入参数出卷题目数量,出卷人,出卷的类型。

并把出的试卷生成并保存在该用户的目录下,以出卷时间为命名的txt文件。根据小学加减乘除括号,初中有根号或者平方,高中有三角函数来进行分类编写,用rand产生随机数来确定使用什么操作数,操作符,操作数大小,并用string进行拼接,虽然满足了加减乘除,但是在特殊符号的处理上只放在第一位来对算术进行特殊化,如sin50+6*5=。

void get(int NUM, int USER, int TYPE) {
  time_t t = time(NULL);
  ofstream File;
  char ttime[33];
  // 确定用户
  switch (USER) {
    case 1: {
      strftime(ttime, 33, "./张三1/%Y-%m-%d-%H-%M-%S.txt", localtime(&t));
      break;
    }
    case 2: {
      strftime(ttime, 33, "./张三2/%Y-%m-%d-%H-%M-%S.txt", localtime(&t));
      break;
    }
    case 3: {
      strftime(ttime, 33, "./张三3/%Y-%m-%d-%H-%M-%S.txt", localtime(&t));
      break;
    }
    case 4: {
      strftime(ttime, 33, "./李四1/%Y-%m-%d-%H-%M-%S.txt", localtime(&t));
      break;
    }
    case 5: {
      strftime(ttime, 33, "./李四2/%Y-%m-%d-%H-%M-%S.txt", localtime(&t));
      break;
    }
    case 6: {
      strftime(ttime, 33, "./李四3/%Y-%m-%d-%H-%M-%S.txt", localtime(&t));
      break;
    }
    case 7: {
      strftime(ttime, 33, "./王五1/%Y-%m-%d-%H-%M-%S.txt", localtime(&t));
      break;
    }
    case 8: {
      strftime(ttime, 33, "./王五2/%Y-%m-%d-%H-%M-%S.txt", localtime(&t));
      break;
    }
    case 9: {
      strftime(ttime, 33, "./王五3/%Y-%m-%d-%H-%M-%S.txt", localtime(&t));
      break;
    }
  }
  File.open(ttime);
  int randNum = 0;
  int diff = 0;
  // 确定类型
  switch (TYPE) {
    case 1: {
      diff = 0;
      break;
    }
    case 2: {
      diff = 2;
      break;
    }
    case 3: {
      diff = 5;
      break;
    }
  }
  int syn = 0, spin = 0;
  // 生成题目
  for (int i = 1; i <= NUM; i++) {
    File << i << ". " << endl;
    if (diff == 0) {
      randNum = rand() % 4 + 2;
    } else {
      randNum = rand() % 5 + 1;
    }
    int Number[randNum] = {0, 0, 0, 0, 0};
    string sNumber[randNum] = {"", "", "", "", ""};
    for (int j = 0; j < randNum; j++) {
      Number[j] = rand() % 100 + 1;
      sNumber[j] = to_string(Number[j]);
    }
    string FileWrite = "";
    if (diff == 0) {
      spin = 0;
    } else if (diff == 2) {
      spin = rand() % 2 + 1;
    } else if (diff == 5) {
      spin = rand() % 3 + 3;
    }
    string spis = "";
    switch (spin) {
      case 0: {
        FileWrite = FileWrite + sNumber[0];
        break;
      }
      case 1: {
        spis = spis + "^2";
        FileWrite = FileWrite + sNumber[0];
        FileWrite = FileWrite + spis;
        break;
      }
      case 2: {
        spis = spis + "√";
        FileWrite = FileWrite + spis;
        FileWrite = FileWrite + sNumber[0];
        break;
      }
      case 3: {
        spis = spis + "sin";
        FileWrite = FileWrite + spis;
        FileWrite = FileWrite + sNumber[0];
        break;
      }
      case 4: {
        spis = spis + "cos";
        FileWrite = FileWrite + spis;
        FileWrite = FileWrite + sNumber[0];
        break;
      }
      case 5: {
        spis = spis + "tan";
        FileWrite = FileWrite + spis;
        FileWrite = FileWrite + sNumber[0];
        break;
      }
    }
    if (randNum != 1) {
      int flag = 0;
      int dir = 0;
      for (int j = 1; j < randNum; j++) {
        syn = rand() % 4;
        string symbol = "";
        switch (syn) {
          case 0: {
            symbol = symbol + '+';
            break;
          }
          case 1: {
            symbol = symbol + '-';
            break;
          }
          case 2: {
            symbol = symbol + '*';
            break;
          }
          case 3: {
            symbol = symbol + '/';
            break;
          }
        }
        FileWrite = FileWrite + symbol;
        if ((rand() % 3 == 1) &&
            (flag == 0) &&
            (j != randNum - 1)) {
          FileWrite = FileWrite + "(";
          flag = 1;
          dir = j;
        }
        FileWrite = FileWrite + sNumber[j];
        if ((dir != j) &&
            (flag == 1) &&
            (rand() % 3 == 2)) {
          FileWrite = FileWrite + ")";
          flag = 2;
        }
      }
      if (flag == 1) {
        FileWrite = FileWrite + ")";
        flag = 2;
      }
    }
    if (find(FileWrite, USER) == 1) {
      File << FileWrite;
      File << endl << endl;
    } else {
      i = i - 1;
    }
  }
  File.close();
}
View Code

(4)查重

首先是传入该用户的信息,以此来进入该用户目录下的文件,在遍历目录下所有文件,进入文件中的txt,提取每一行成string,并于出的题作比较,如果相同返回-1,如果不同返回1.

void getFiles(string path, vector<string> &files) {
  // 文件句
  int16_t hFile = 0;
  // 文件信息
  struct _finddata_t fileinfo;
  string pathName;
  if ((hFile = _findfirst(pathName.assign(path).c_str(), &fileinfo)) != -1) {
    do {
        if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
          files.push_back(pathName.assign(path).
                          append("/").append(fileinfo.name));
    } while (_findnext(hFile, &fileinfo) == 0);
    _findclose(hFile);
  }
}
// 查重函数:将先前的文档进行遍历,
// 然后在提取出每一行的字符串,
// 比较每一行的字符串,
// 若没有重复则返回1,重复了就返回-1
int find(string test, int ty) {
  string FindType = "";
  switch (ty) {
    case 1: {
      FindType = "./张三1/";
      break;
    }
    case 2: {
      FindType = "./张三2/";
      break;
    }
    case 3: {
      FindType = "./张三3/";
      break;
    }
    case 4: {
      FindType = "./李四1/";
      break;
    }
    case 5: {
      FindType = "./李四2/";
      break;
    }
    case 6: {
      FindType = "./李四3/";
      break;
    }
    case 7: {
      FindType = "./王五1/";
      break;
    }
    case 8: {
      FindType = "./王五2/";
      break;
    }
    case 9: {
      FindType = "./王五3/";
      break;
    }
  }
  vector<string> files;
  getFiles(FindType, files);
  int size = files.size();
  for (int i = 0; i < size; i++) {
    ifstream fin(files[i]);
    string past;
    while (fin >> past) {
      if (past == test)
        return (-1);
    }
  }
  return 1;
}
查重

三总结

优点:

本次编程基本实现了功能,在每个用户下正确出小学,初中,高中试卷,出卷题目满足要求。代码使用get函数进行出题,getFile和find函数进行查重,查重通过才写入txt。

缺点:

注释太少,操作数,操作符的注释没有,让人刚开始理解起来不是那么流畅。功能实现有不合理性,因为只在第一位数字才进行特殊化处理,题目就没有那么合理性。

评价:

我的也是使用的是C++,大体是一样的,但是在出题的时候,他是三份类型试卷一起写,理解起来较为困难。对比起来,总会发现自己与他人的差别,在之后也会学习别人的优点,运用更好的方法。

这篇关于湖南大学结队编程项目队友代码互评的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!