建立文件版题库
- 题目的编号
- 题目的标题
- 题目的难度
- 题目的描述,题面
- 时间要求(内部处理)
- 空间要求(内部处理)
两批文件构成 - 第一个: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"
#endif
void 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"
#endif
void 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"
#endif
void 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 30000
if(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 split
boost::split((*target), str, boost::is_any_of(sep), boost::algorithm::token_compress_on);
}
};