前言
当你在写一个无论是简单还是复杂的算法,无论是在面试中,工作中,还是算法比赛中,一个最最重要的目的就是保证你算法的正确性。其实大家可以仔细想想,要实现这个目的真的不是那么容易。下面我们分场景讨论这些情况:
- 当你在刷各种OJ时候:当你满心欢喜的把自己的算法放入OJ进行测试时,如果你过了的话,那还万事大吉,但是,当你没过的话,问题就来了
- 第一OJ不一定会给你显示出错的测试用例
- 第二,即使给你显示,也极有可能是这样一种情况:简单的小样本过了,但是死在了一些复杂的样本,这样的样本即便给了你,你拿着这样的样本去修改你的算法也是很痛苦的。
- 在面试的时候,当你费了九牛二虎之力写出来一个算法,你拿着你的小用例也跑过了,但是你敢拍胸脯说这个算法没问题了么,尤其是扣边界相关的BUG,所以在这个时候有个办法来尽最大可能来保证算法是对的,是很重要的。
- 在工作中,当你根据实际的需求,写了一个自己自我感觉还不错的算法,尤其是已经交付使用的代码,很明显你不可能放心的就交给客户去用,万一出现了BUG,那就。。。。所以这个时候也需要一个方法来最大可能保证你的算法的正确性。
所以它来了,它就是对数器,含义很简单:就是一个数一个数去对着去比较,这里的对数和数学中的对数概念没有半毛钱的关系,在网上看到好多人把对数器相关的函数名或类名什么的都取成了logarithm之类的,其实这种名字就不应该了。
1.对数器的概念和使用
- 0,有一个你想要测的方法a
- 1,实现一个绝对正确但是复杂度不好的方法b,
- 2,实现一个随机样本产生器
- 3,实现比对的方法
- 4,把方法a和方法b比对很多次来验证方法a是否正确
- 5,如果有一个样本使得比对出错,打印样本分析是哪个方法出错
- 6,当样本数量很多时比对测试依然正确,可以确定方法a已经正确
这里我个人对对数器的认识是可以为你锦上添花,即你基本能写出算法的情况下,对数器可以用来帮你扣边界什么的,来确定算法的正确性,但它不会雪中送炭,当你本身就写不出来算法的时候,很明显,这个时候对数器就卵用都没了。
2.C++版本的对数器
2.1 C++版本数组排序对数器
这里作为一个对数器最简单的实现范例:对数器的作用是为了验证一个排序算法的正确性,我把对数器相关实现的几个重要函数我都封转到了一个类中,大家需要的话直接拿去用就可以了。(这里用到了两个C++11的标准库,一个是vector,另一个随机数发生器。)
代码见下:
compareNumGeneratorSort.h
#ifndef __COMPARE_GENERATOR__
#define __COMPARE_GENERATOR__
#include<iostream>
#include<vector>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<random>
#define random() rand()/double(RAND_MAX)
using namespace std;
struct Array{
vector<int> ivec;
};
class compareGenerator{
public:
Array generateRandomArray(int,int);
void rightMathod(Array&);
const Array& copyArray(const Array&);
bool isEqual(const Array&,const Array&);
void printArray(const Array&);
};
#endif
compareNumGeneratorSort.cpp
#include"compareNumGeneratorSort.h"
Array compareGenerator::generateRandomArray(int size,int value){
static default_random_engine e;
static uniform_int_distribution<unsigned> u1(0,size);
static uniform_int_distribution<signed> u2(-value,value);
int length = u1(e);
Array temp;
for(int i=0 ; i<length ; i++){
temp.ivec.push_back(u2(e));
}
return temp;
}
void compareGenerator::rightMathod(Array& array){
sort(array.ivec.begin(),array.ivec.end());
}
const Array& compareGenerator::copyArray(const Array& array)
{
return array;
}
bool compareGenerator::isEqual(const Array &array1,const Array &array2){
if((array1.ivec.size() == 0 && array2.ivec.size() != 0) ||
(array1.ivec.size() != 0 && array2.ivec.size() == 0))
{
return false;
}
if(array1.ivec.size() == 0 && array2.ivec.size() == 0)
{
return true;
}
if(array1.ivec.size() != array2.ivec.size())
{
return false;
}
for(int i = 0; i < array1.ivec.size(); i++)
{
if(array1.ivec[i] != array2.ivec[i])
{
return false;
}
}
return true;
}
void compareGenerator::printArray(const Array& array){
for(auto i:array.ivec)
{
cout<<i<<" ";
}
cout<<endl;
}
点击下载上述示例代码,其实没必要下载,自己从代码框复制就可以了