事情开始于大二上学期,有一门叫做《网站建设与管理》的课程。本人由于对Web方面比较有兴趣,又比较喜欢Python语言的风格,于是就边学老师教的PHP边学了Django。正好大一下学期学了算法,对算法和各种OJ都比较有兴趣,所以就写了一个不能评测的手动OJ当期末大作业交了上去。这个暑假开始着手将这个网站建成一个能评测的真OJ。在知乎和Github上爬了一段时间,找到了https://github.com/KIDx/Judger这么一个开源项目,把这个项目的代码改动了不少之后终于可以跑起来了。自己的OJ地址在:http://111.230.131.247/JudgeHome/

目前使用之后发现原OJ系统对Presentation Error的判定过于严格,于是这里想将它改为去除行末空格与文末空行后比对的模式。将程序中与文本比对相关的算法提取出来,得到了一个用于文本比对的小程序:

 1 #include <iostream>
 2 using namespace std;
 3
 4 void compare_until_nonspace(int &c_std, int &c_usr, FILE *&fd_std, FILE *&fd_usr, int &ret)
 5 {
 6     while((isspace(c_std)) || (isspace(c_usr)))
 7     {
 8         if (c_std != c_usr)
 9         {
10             if (c_std == '\r' && c_usr == '\n')
11             {
12                 c_std = fgetc(fd_std);
13                 if (c_std != c_usr)
14                     ret = 3; //PRESENTATION ERROR
15             }
16             else
17             {
18                 ret = 3; //PRESENTATION ERROR
19             }
20         }
21         if (isspace(c_std))
22             c_std = fgetc(fd_std);
23         if (isspace(c_usr))
24             c_usr = fgetc(fd_usr);
25     }
26 }
27
28 int tt_compare_output(string &file_std, string &file_usr)
29 {
30     int ret = 1; //ACCEPTED
31     int c_std, c_usr;
32     FILE *fd_std = fopen(file_std.c_str(), "r");
33     FILE *fd_usr = fopen(file_usr.c_str(), "r");
34
35     if (fd_std == NULL)
36     {
37         printf("%s open standard file failed %s\n", strerror(errno), file_std.c_str());
38     }
39
40     if (!fd_std || !fd_usr)
41     {
42         ret = -1; //RUNTIME ERROR (ABORTION)
43     }
44     else
45     {
46         c_std = fgetc(fd_std);
47         c_usr = fgetc(fd_usr);
48         for(;;)
49         {
50             compare_until_nonspace(c_std, c_usr, fd_std, fd_usr, ret);
51             while(!isspace(c_std) && !isspace(c_usr))
52             {
53                 //    LOG_DEBUG("std: %c usr: %c", c_std, c_usr);
54                 if (c_std == EOF && c_usr == EOF)
55                     goto end;
56                 if (c_std != c_usr)
57                 {
58                     ret = 2; //WRONG ANSWER
59                     goto end;
60                 }
61                 c_std = fgetc(fd_std);
62                 c_usr = fgetc(fd_usr);
63             }
64         }
65     }
66 end:
67     if (fd_std)
68         fclose(fd_std);
69     if (fd_usr)
70         fclose(fd_usr);
71     return ret;
72 }
73
74 int main() {
75     string file_std = "std.txt";
76     string file_usr = "usr.txt";
77     int res = tt_compare_output(*&file_std, *&file_usr);
78     switch(res) {
79         case -1: cout << "RUNTIME ERROR (ABORTION)" << endl; break;
80         case 1: cout << "ACCEPTED" << endl; break;
81         case 2: cout << "WRONG ANSWER" << endl; break;
82         case 3: cout << "PRESENTATION ERROR" << endl; break;
83         default: cout << "SYSTEM ERROR" << endl;
84     }
85     return 0;
86 }

测试该程序,可知usr.txt与std.txt只要有任何一点微小的差别,程序就会输出PRESENTATION ERROR。增加了如下一个逻辑简单的函数之后,就可以实现先将标准输出和选手输出中的行末空格和文末空行都去掉再进行比较了。

void remove_blank(string file) {//删除文末空行和行末空格fstream target_file(file.c_str(), fstream::in | fstream::out);string line; //作为读取的一行string temp; //用作缓存vector<string> obj; //用于储存整理完成后的每一行if(!target_file) {cout << "Can't open target file!" << endl; //上线后改成LOG_DEBUG
    }while(getline(target_file, line)) {unsigned long len = line.length();int count = 0;for(unsigned long i=len-1; i>=0; i--) {int temp_char = line[i]; //用于将字符转换为ASCII码,保存ASCII码使用if(isspace(temp_char))count++;else break;}temp = line.substr(0, len-count);obj.push_back(temp);}int count_lines = 0; //文末空行的数量for(unsigned long i=obj.size()-1; i>=0; i--) {//去除文末空行if(obj[i].empty())count_lines++;else break;}cout << "count_lines: " << count_lines << endl;for(int i=0; i<count_lines; i++)obj.pop_back();//使用ofstream打开再关闭文件是为了清空源文件
    ofstream empty_file(file.c_str());empty_file.close();//重新打开文本文件fstream target(file.c_str(), fstream::out | fstream::in);if(!target) {cerr << "Can't open file" << endl; //上线后改成LOG_DEBUG
    }//写回源文件for(unsigned long i=0; i<obj.size(); i++)target << obj[i] << endl;target.close();
}

要注意的是,在Linux的g++编译器下,fstream、ofstream等的参数需要是c类型的字符串,需要将普通的string类型通过c_str转换为c类型的字符串才可以通过编译。而本人所使用的mac下clang编译器并没有这种要求,直接使用string类型也可以通过编译。这里debug了很久,一定要小心。

转载于:https://www.cnblogs.com/Akatsuki-Sanjou/p/11161285.html

搭建Aqours Online Judge的琐琐碎碎(一)Presentation Error判定相关推荐

  1. 搭建Aqours Online Judge的琐琐碎碎(二)为什么我更新了18.04之后就ssh不上去了啊?...

    事情发生在前几天,我闲着无聊通过Windows下的git bash连接到服务器,看到很久之前开始就挂在那里的18.04更新,于是命令行敲下do--release-upgrade,等着服务器慢慢自己跑更 ...

  2. 出现Presentation Error的解决方法

    出现Presentation Error的解决方法 参考文章: (1)出现Presentation Error的解决方法 (2)https://www.cnblogs.com/mjn1/p/11233 ...

  3. 简单理解hduoj 1106 附ac题解以及Presentation Error避坑

    不得不说hduoj真的严,这题首先自己没有考虑特殊情况,其次因为格式问题Presentation Error. 注意:出现Presentation Error,可以恭喜你了,题解应该没问题,就是空行, ...

  4. Android 开发环境搭建 与在编译中遇到错误make Error 45解决方法

    Android 开发环境搭建 一.安装ubuntu 10.10操作系统 使用光盘安装,注意分区,分一个swap分区为3G(原则需要与内存一样大,但可以稍微比内存大一点).当时是同事帮我弄的,swap开 ...

  5. 搭建go开发环境时,出现GoSublime error: MarGo build failed的问题

    在安装问go语言开发工具,Sublime Text Build 3083之后,再安装gocode和margo时,在安装margo那一步卡住了,出现了以下问题: GoSublime error: Mar ...

  6. zjfc----1076 online judge 对多行字符串输入做处理

    题目描述 Ignatius is building an Online Judge, now he has worked out all the problems except the Judge S ...

  7. Bailian2793 孙子问题【扩展欧几里德算法+中国剩余定理】

    2793:孙子问题 总时间限制: 15000ms 内存限制: 65536kB 描述 我国古代<孙子算经>中,记有如下算题:"今有物不知其数,三三数之剩二,五五数之剩三,七七数之剩 ...

  8. ACM集训STL(1)学习杂记(二)——E题~H题

    STL(1) (E)Online Judge 很简单的一道题,再看自己的代码会发现一些没必要的地方. Online Judge Ignatius is building an Online Judge ...

  9. 算法竞赛:Online Judge介绍

    专栏:算法竞赛 上一篇: 下一篇: 文章目录 一.什么是Online Judge 二.Online Judge 网站 1. 洛谷 2. LeetCode 力扣 3. 牛客 4. PTA 拼题A 三.算 ...

最新文章

  1. Python中的元类(metaclass)
  2. Microsoft uaa bus driver for high definition audio
  3. Elasticseach 从零开始学习记录(三) - 分布式部署
  4. asp.net中URL参数加密解密过程
  5. ubuntu iptables设置
  6. 报告:2015年数据中心SDN市场将增长70%
  7. 人工智能数学基础之概率论
  8. java List 排序 Collections.sort()
  9. Sharepoint学习笔记---SPList--External List因BCS的Throttling limit 节流限制导致的错误
  10. Julia : 如何进一步改进操作Redis的效率?
  11. 读书:Jenkins权威指南[2016京东畅销书]
  12. 一键定制个性化语音,微软的AI语音落地实践
  13. 空手套白狼,放端套利
  14. 我可以利用计算机查找资料,《信息检索》复习题库 (1)
  15. 基于Python网络爬虫的小说网站数据分析
  16. Web前端-JavaScript--对象
  17. U盘用哪种格式化比较好?教你一步,详细区分U盘格式
  18. 求平均数(1~10)
  19. SQL语句:where条件后写上1=1是为了什么
  20. 计算机与代数---如何计算ln---方法和实现

热门文章

  1. windows邮箱无法登录腾讯企业邮箱
  2. Qt 自定义鼠标控制窗口移动
  3. 永磁同步电机的直接转矩控制(一)一一一DTC仿真模型的搭建
  4. JavaScript的输出与变量
  5. 80句励志名言名句-用来时刻鞭策自己
  6. 每日格言积累及总结——更新中
  7. 新华三杯复赛实验-虚拟局域网与IPv4 IGP路由部署解析
  8. weixin小程序和公众号抓包方法分享
  9. 【weJudge】1106. [ACM][2014新生赛重现][现场]Gundam Unicorn
  10. java基础数据类型和运算符