建立文件版题库
- 题目的编号
- 题目的标题
- 题目的难度
- 题目的描述,题面
- 时间要求(内部处理)
- 空间要求(内部处理)
两批文件构成 - 第一个:questions.list : 题目列表(不需要题目的内容)
- 第二个:题目的描述,题目的预设置代码(header.cpp), 测试用例代码(tail.cpp)
这两个内容是通过题目的编号,产生关联的
题目1判断回文数
question.list
1 判断回文数 简单 ? 1 30000
desc.txt
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。示例 1:输入: 121
输出: true
示例 2:输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。
进阶:你能不将整数转为字符串来解决这个问题吗?
header.cpp
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>using namespace std;class Solution{public:bool isPalindrome(int x){//将你的代码写在下面return true;}
};
tail.cpp
#ifndef COMPILER_ONLINE
#include "header.cpp"
#endifvoid Test1()
{// 通过定义临时对象,来完成方法的调用bool ret = Solution().isPalindrome(121);if(ret){std::cout << "通过用例1, 测试121通过 ... OK!" << std::endl;}else{std::cout << "没有通过用例1, 测试的值是: 121" << std::endl;}
}void Test2()
{// 通过定义临时对象,来完成方法的调用bool ret = Solution().isPalindrome(-10);if(!ret){std::cout << "通过用例2, 测试-10通过 ... OK!" << std::endl;}else{std::cout << "没有通过用例2, 测试的值是: -10" << std::endl;}
}int main()
{Test1();Test2();return 0;
}
OJ不是只把header.cpp的代码提交给compile_and_run, 而是把header.cpp和tail.cpp合并成一个文件,最终提交给后台编译运行服务的代码是
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>using namespace std;class Solution{public:bool isPalindrome(int x){//将你的代码写在下面return true;}
};#ifndef COMPILER_ONLINE
#include "header.cpp"
#endifvoid Test1()
{// 通过定义临时对象,来完成方法的调用bool ret = Solution().isPalindrome(121);if(ret){std::cout << "通过用例1, 测试121通过 ... OK!" << std::endl;}else{std::cout << "没有通过用例1, 测试的值是: 121" << std::endl;}
}void Test2()
{// 通过定义临时对象,来完成方法的调用bool ret = Solution().isPalindrome(-10);if(!ret){std::cout << "通过用例2, 测试-10通过 ... OK!" << std::endl;}else{std::cout << "没有通过用例2, 测试的值是: -10" << std::endl;}
}int main()
{Test1();Test2();return 0;
}
下面的代码,我们不想让编译器编译的时候,保留它,而是裁剪掉
(g++ -D COMPILER_ONLINE)
仅仅是为了让我们设计测试用例的时候,不要报错
#ifndef COMPILER_ONLINE
#include "header.cpp"
#endif
题目2求最大值
question.list
1 判断回文数 简单 1 30000
2 求最大值 简单 1 30000
desc.txt
求最大值,比如:vector v ={1,2,3,4,5,6,12,3,4,-1};
求最大值, 比如:输出 12
header.cpp
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;class Solution
{
public:int Max(const vector<int> &v){//将你的代码写在下面return 0;}
};
tail.cpp
#ifndef COMPILER_ONLINE
#include "header.cpp"
#endifvoid Test1()
{vector<int> v = {1, 2, 3, 4, 5, 6};int max = Solution().Max(v);if (max == 6){std::cout << "Test 1 .... OK" << std::endl;}else{std::cout << "Test 1 .... Failed" << std::endl;}
}void Test2()
{vector<int> v = {-1, -2, -3, -4, -5, -6};int max = Solution().Max(v);if (max == -1){std::cout << "Test 2 .... OK" << std::endl;}else{std::cout << "Test 2 .... Failed" << std::endl;}
}int main()
{Test1();Test2();return 0;
}
编写model文件
代码框架
oj_model.hpp
#pragma once#include "../comm/log.hpp"#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <cassert>// 根据题目list文件,加载所有的题目信息到内存中
// model: 主要用来和数据进行交互,对外提供访问数据的接口namespace ns_model
{using namespace std;using namespace ns_log;struct Question{std::string number; //题目编号,唯一std::string title; //题目的标题std::string star; //难度: 简单 中等 困难int cpu_limit; //题目的时间要求(S)int mem_limit; //题目的空间要去(KB)std::string desc; //题目的描述std::string header; //题目预设给用户在线编辑器的代码std::string tail; //题目的测试用例,需要和header拼接,形成完整代码};const std::string question_list = "./questions/questions.list"class Model{private://题号:题目细节unordered_map<string, Question> questions;public:Model(){assert(LoadQuestionList());}LoadQuestionList(const std::string &question_list){//加载配置文件:questions/questions.list}void GetAllQuestions(vector<Question> *out){}void GetOneQuestion(const std::string &number, Question *q){}~Model(){}};
}
完整
oj_model.hpp
#pragma once
//文件版本
#include "../comm/util.hpp"
#include "../comm/log.hpp"#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <fstream>
#include <cstdlib>
#include <cassert>// 根据题目list文件,加载所有的题目信息到内存中
// model: 主要用来和数据进行交互,对外提供访问数据的接口namespace ns_model
{using namespace std;using namespace ns_log;using namespace ns_util;struct Question{std::string number; //题目编号,唯一std::string title; //题目的标题std::string star; //难度: 简单 中等 困难int cpu_limit; //题目的时间要求(S)int mem_limit; //题目的空间要去(KB)std::string desc; //题目的描述std::string header; //题目预设给用户在线编辑器的代码std::string tail; //题目的测试用例,需要和header拼接,形成完整代码};const std::string questins_list = "./questions/questions.list";const std::string questins_path = "./questions/";class Model{private://题号 : 题目细节unordered_map<string, Question> questions;public:Model(){assert(LoadQuestionList(questins_list));}bool LoadQuestionList(const string &question_list){//加载配置文件: questions/questions.list + 题目编号文件ifstream in(question_list);if(!in.is_open()){LOG(FATAL) << " 加载题库失败,请检查是否存在题库文件" << "\n";return false;}string line;while(getline(in, line)){vector<string> tokens;StringUtil::SplitString(line, &tokens, " ");// 1 判断回文数 简单 1 30000if(tokens.size() != 5){LOG(WARNING) << "加载部分题目失败, 请检查文件格式" << "\n";continue;}Question q;q.number = tokens[0];q.title = tokens[1];q.star = tokens[2];q.cpu_limit = atoi(tokens[3].c_str());q.mem_limit = atoi(tokens[4].c_str());string path = questins_path;path += q.number;path += "/";FileUtil::ReadFile(path+"desc.txt", &(q.desc), true);FileUtil::ReadFile(path+"header.cpp", &(q.header), true);FileUtil::ReadFile(path+"tail.cpp", &(q.tail), true);questions.insert({q.number, q});}LOG(INFO) << "加载题库...成功!" << "\n";in.close();return true;}bool GetAllQuestions(vector<Question> *out){if(questions.size() == 0){LOG(ERROR) << "用户获取题库失败" << "\n";return false;}for(const auto &q : questions){out->push_back(q.second); //first: key, second: value}return true;}bool GetOneQuestion(const std::string &number, Question *q){const auto& iter = questions.find(number);if(iter == questions.end()){LOG(ERROR) << "用户获取题目失败, 题目编号: " << number << "\n";return false;}(*q) = iter->second;return true;}~Model(){}};
} // namespace ns_model
使用boost split字符串切分
安装boost库
sudo yum install -y boost-devel
测试
#include <iostream>
#include <vector>
#include <boost/algorithm/string.hpp>
int main()
{std::vector<std::string> tokens;const std::string str = "1:判断回文数::::::简单:1:30000";const std::string sep = ":";boost::split(tokens, str, boost::is_any_of(sep), boost::algorithm::token_compress_on);for(auto &iter : tokens){std::cout << iter << std::endl;}}
编译
g++ test.cc -std=c++11
#include <iostream>
#include <vector>
#include <boost/algorithm/string.hpp>
int main()
{std::vector<std::string> tokens;const std::string str = "1:判断回文数::::::简单:1:30000";const std::string sep = ":";boost::split(tokens, str, boost::is_any_of(sep), boost::algorithm::token_compress_off);for(auto &iter : tokens){std::cout << iter << std::endl;}}
util.hpp
class StringUtil{public:/************************************** str: 输入型,目标要切分的字符串* target: 输出型,保存切分完毕的结果* sep: 指定的分割符* **********************************/static void SplitString(const std::string &str, std::vector<std::string> *target, const std::string &sep){//boost splitboost::split((*target), str, boost::is_any_of(sep), boost::algorithm::token_compress_on);}};