基于c++11泛型编程开发一个LeetCode本地开发测试组件
来源:互联网 发布:瑞安法院淘宝拍卖网 编辑:程序博客网 时间:2024/06/06 23:19
LeetCode初次接触感觉还不错,重点是可以对比讨论共同实现的一段代码,https://leetcode.com。
处理复杂问题不适合在OJ上直接开发,本地调试更简单。暂时(我想应该会有)未发现可以直接拿来运行的框架,自己简单实现一个,未来发现更好的再补充。
注意:只以用c++11,g++编译选项-std=c++11
一个需要两个文件,下载文件
leetcode.h 包含一些流程控制和通用api(临时写的,需要时补全)
main.cpp 实现一些差异化接口即可
功能:执行指定的数据的测试,自动进行5组随机测试
验证:可以人工核验,也可以指定一个确定的通过代码,对比校验另一下
用法 : class Q1 : public Solution<RetType, ParamList>
RetType表示接口返回类型,具体题目具体替换,不要用引用,不然模板有冲突
ParamList是逗号间隔的所有函数参数列表,这里使用了不定参数模板
实现基类所有纯虚函数
后文给出了第一题和第3题的示例Demo。
一、leetcode.h
#include <iostream>#include <random>#include <map>#include <unordered_map>#include <cassert>#include <algorithm>#include <cstring>using namespace std;class Interface{public: virtual void RandomTest(uniform_int_distribution<int>& u, default_random_engine& e) = 0;};template<typename RT, typename ...ARGS>class Solution : virtual public Interface{ typedef RT (Solution::*deal_fun_t)(ARGS...); //定义5个回调算法 virtual RT FUN_NAME_0(ARGS...) { return RT(); } virtual RT FUN_NAME_1(ARGS...) { return RT(); } virtual RT FUN_NAME_2(ARGS...) { return RT(); } virtual RT FUN_NAME_3(ARGS...) { return RT(); } virtual RT FUN_NAME_4(ARGS...) { return RT(); } virtual RT FUN_NAME_5(ARGS...) { return RT(); } deal_fun_t m_fun[5]; // virtual bool CheckRst(RT&, RT&, ARGS...) const = 0; virtual void DumpInput(ARGS...) = 0; // bool m_debug; int m_id;public: void SetConf(int id, bool debug) { m_id =id; m_debug = debug; } //构造初始化指定算法 Solution(int no = 0) { m_fun[0] = &Solution::FUN_NAME_0; m_fun[1] = &Solution::FUN_NAME_1; m_fun[2] = &Solution::FUN_NAME_2; m_fun[3] = &Solution::FUN_NAME_3; m_fun[4] = &Solution::FUN_NAME_4; m_fun[5] = &Solution::FUN_NAME_5; } //测试并打印相关信息 void Test(ARGS...arg) { cout << "----------------" << endl; DumpInput(arg...); auto rst1 = FUN_NAME_0(arg...); auto rst2 = (this->*m_fun[m_id])(arg...); if(CheckRst(rst1, rst2, arg...)) cout << "succ" << endl; else { cout << "fail" << endl; assert(!m_debug); } } //公共库存 //随机vector vector<int> RandomVector(uniform_int_distribution<int>& u, default_random_engine& e, int min) { int len = u(e)+min; vector<int> data(len); for(int i = 0; i < len; i++) data[i] = u(e); return data; } //随机字符串 string RandomString(uniform_int_distribution<int>& u, default_random_engine& e, int min) { int len = u(e)+1; static char s_str[] = "abcdefghijklmnopqrstuvwxvzABCDEFGHIJKLMNOPQRSTUVWXVZ"; char* ptr = s_str, *end=s_str+52; string rst; for(int i = 0; i < len; i++) { ptr += u(e); if(ptr >= end) ptr = s_str; rst += (char)ptr[0]; } return rst; } //vector<int>转字符串 string VecToStr(vector<int>& arr, char sep) { string str; char buf[32]; for(auto &i : arr) { sprintf(buf, "%d%c", i, sep); str += buf; } return str; }};//mainInterface* GetObj(int argc, char* argv[], char* env[]);int main(int argc, char* argv[], char* env[]){ Interface* s = GetObj(argc, argv, env); if(s == nullptr) return 0; //随机测试 uniform_int_distribution<int> u(0, 9); default_random_engine e; e.seed(time(0)); for(int i = 0; i < 5; i++) //随机测试5组 s->RandomTest(u, e); return 0;}
第一题示例:
#include "leetcode.h"//use class Q1 : public Solution<RetType, ParamList>class Q1 : public Solution<int, string>{public: Q1(int id, bool debug = true) { SetConf(id, debug); } //一次随机测试 void RandomTest(uniform_int_distribution<int>& u, default_random_engine& e) override { Test(RandomString(u, e, 0)); } //输出输入信息 void DumpInput(string str) override { cout << "input: " << str << endl; } //输出字符串化以比较 r0是标准函数返回结果, r1是自定义函数结果 bool CheckRst(int& r0, int& r1, string s) const override { cout << "rst " << r0 << "," << r1 << endl; return r0 == r1; } int FUN_NAME_0(string s) override { vector<int> pos(127, -1); int max = 0; int repeat = -1; int len = s.length(); for(int i = 0; i < len; i++) { if(pos[s[i]] > repeat) repeat = pos[s[i]]; pos[s[i]] = i; int len = i - repeat; if(len > max) max = len; } return max; } int FUN_NAME_1(string s) override { char c[128]; memset(c, 0, sizeof(c)); const char* p = s.c_str(); int len1 = 0, max = 0; while(*p != '\0') { int pos = (char)*p; if(c[pos] != 0) { while(p[-len1] != *p) { pos = p[-len1]; --c[pos]; --len1; } pos = p[-len1]; --c[pos]; --len1; } pos = *p; c[pos]++; p++; len1++; if(max < len1) max = len1; } return max; }};Interface* GetObj(int argc, char* argv[], char* env[]){ Q1* s = new Q1(1, false); //指定使用1号算法 //返回之前可以进行一些内部测试 s->Test("heecagga"); s->Test("eecdb"); s->Test("dfhgd"); s->Test("abcabcbb"); s->Test("bbbbb"); s->Test("pwwkew"); return s;}
#include "leetcode.h"//use class Q1 : public Solution<RetType, ParamList>class Q3 : public Solution<vector<int>, vector<int>, int>{public: Q3(int id, bool debug = true) { SetConf(id, debug); } //一次随机测试 void RandomTest(uniform_int_distribution<int>& u, default_random_engine& e) override { Test(RandomVector(u, e, 2), u(e)); } //输出输入信息 void DumpInput(vector<int> nums, int target) override { cout << "sum: " << target << " | " << VecToStr(nums, ' ') << endl; } //输出字符串化以比较 r0是标准函数返回结果, r1是自定义函数结果 bool CheckRst(vector<int>& r0, vector<int>& r1, vector<int> nums, int target) const override { cout << r0[0] << "," << r0[1] << endl << r1[0] << "," << r1[1] << endl; return nums[r1[0]] + nums[r1[1]] == nums[r0[0]] + nums[r0[1]]; //1和2结果对比 //return (nums[r1[0]] + nums[r1[1]] == target) && (nums[r0[0]] + nums[r0[1]] == target) //全量校验以避免参考答案有误 } //算法1,普通算法,a+b=target,遍历一次数组,每个数,即可能是a,也可能是b,将a起来。如果找到了当前数的a,则成功 //9ms 54.37, 再提交2次,6ms和12ms vector<int> FUN_NAME_0(vector<int> nums, int target) override { unordered_map<int, int> subs; const int max = nums.size(); for(int i = 0; i < max; i++) { auto it = subs.find(target-nums[i]); if(it != subs.end()) return vector<int> {it->second, i}; subs[nums[i]] = i; } return vector<int> {-1, -1}; } //算法2,改进最佳答案,用map同时实现排序和反查,降低反查代价,损耗一些排序性能(相对快速排序) //18ms, 41.35%, 并没有成功,原因是数据量小的情况下,得不偿失 vector<int> FUN_NAME_1(vector<int> nums, int target) override { multimap<int, int> org_pos; for(size_t i = 0; i < nums.size(); i++) org_pos.insert(pair<int,int>(nums[i], i)); auto it_beg = org_pos.begin(); auto it_end = --org_pos.end(); while(it_beg != it_end) { int val = it_beg->first + it_end->first; if(val == target) { if(it_beg->second < it_end->second) return vector<int> {it_beg->second, it_end->second}; else return vector<int> {it_end->second, it_beg->second}; } if(val > target) it_end--; else if(val < target) it_beg++; } return vector<int> {-1, -1}; }};Interface* GetObj(int argc, char* argv[], char* env[]){ Q3* s = new Q3(1, false); //指定使用1号算法 //返回之前可以进行一些内部测试 //s.Test(vector<int> {3,3}, 6); //指定的固定测试数据 //s.Test(vector<int> {2,7,11,15}, 9); return s;}
一个非常临时的Makefile
CXXFLAGS= -std=c++11 -g -Wallmain: binid1 binid3 ./binid1 ./binid3binid1: id1.cpp g++ ${CXXFLAGS} id1.cpp -o binid1binid3: id3.cpp g++ ${CXXFLAGS} id3.cpp -o binid3
阅读全文
0 0
- 基于c++11泛型编程开发一个LeetCode本地开发测试组件
- 基于组件的开发
- 基于测试的开发
- 基于组件开发主要特征整理
- 基于组件的开发技术
- 基于组件的开发思路
- android C编程技巧 及 C/C++开发测试(转)
- android C编程技巧 及 C/C++开发测试
- android C编程技巧 及 C/C++开发测试
- Android C编程技巧和C/C++开发测试
- 面向对象编程,面向服务架构,基于组件开发三种编程模式有什么区别?
- 基于nodejs实现本地网页服务器-实现手机测试电脑开发的移动端网页
- 基于Django的微信公众号开发(4) -- 配置云数据库和本地测试库
- MUWork--一个基于Objective-c的AOP开发框架
- 【Qt编程】基于Qt的词典开发系列<二>--本地词典的设计
- 开发一个基于React Native的简易demo--视频组件+布局
- storm, kafka集成之本地开发、测试
- 微信开发本地测试环境搭建
- [Android 编译] Ubuntu 16.04 LTS 成功编译 Android 6.0 源码教程
- 一个项目学会前端实现登录拦截
- 『ORACLE』RAC增加节点(11g)
- 中文乱码-Javaweb-request读取时乱码解决方法
- 跳转应用市场 评分等
- 基于c++11泛型编程开发一个LeetCode本地开发测试组件
- 前端设计--HTML,CSS
- 2017/6/29
- springMVC controller间跳转 重定向 传递参数的方法
- Oracle中merge into的使用
- 【C++】类和对象--基础知识+四个默认成员函数+运算符重载
- 源代码文件的扩展名:
- Linux下Vue开发环境搭建一篇全搞定
- Android界面布局文字水印