一、背景
平时我们在进行算法学习或者开发的时候,可能会烦恼无法验证自己写的算法的正确性,因为不可能找到每一道题目可以使用的测试用例。对数器就是一种解决这个问题的方法。
二、对数器的基本思想
我们具有待测的方法,和一个用于对照的方法,使二者跑N组用例,如果所得结果每组用例都相同,则
1、我们自己写的待测方法 funA();
2、和funA实现相同作用的,比较可信的对照组方法 funB();
3、实现一个随机样本产生器,用来生成随机的测试用例;
4、使funA和funB分别运行同一组随机样本,比较运行结果;
5、如果结果有不同,则说明funA或funB存在错误,需要改进;如果结果相同,继续跑下一组样本;
6、如果每组样本都跑得了相同的结果,当样本足够多时,我们就可以认为funA基本正确了。
三、C++代码实现
以冒泡排序算法为例
//待测方法:冒泡排序-上浮 升序
void funA(vector<int>& nums)
{
//i记录参与比较的起始位置
for (int i = 0; i < nums.size(); ++i)
{
bool isSwap = false;//如果isSwap为true,则循环有交换操作
for (int j = nums.size() - 1; j > i; --j)
{
//逆序则交换
if (nums[j] < nums[j - 1]) {
swap(nums[j], nums[j - 1]);
isSwap = true;
}
}
//此轮循环已经有序,不需要再遍历
if (isSwap == false) {
break;
}
}
}
//使用C++提供的库函数实现对照排序方法
void funB(vector<int>& nums)
{
sort(nums.begin(), nums.end());
}
//生成随机数组
std::vector<int> generateRandomArray(int maxSize, int maxNum)
{
srand(time(0));
int arraySize = rand() % (maxSize+1);
std::vector<int> arr(arraySize);
for (int i = 0; i < arraySize; ++i)
{
arr[i] = rand() % (maxNum+1);
}
return arr;
}
//比较两个结果是否相同
bool compareFun(const vector<int>&arr1, const vector<int>&arr2)
{
if (arr1.size() != arr2.size())
{
return false;
}
for (int i = 0; i < arr1.size(); ++i)
{
if (arr1[i] != arr2[i])
{
return false;
}
}
return true;
}
int main(int argc, char *argv[])
{
//跑5000组随机样本
for (int i = 0; i < 5000; ++i)
{
//生成一组样本:最大数组size为456,最大元素数值为754
vector<int> arr1 = generateRandomArray(456, 754);
vector<int> arr2(arr1);
funA(arr1); //待测方法
funB(arr2); //对照方法
//比较两组结果是否相同,如果不同,则失败
if (!compareFun(arr1, arr2))
{
cout << "failed!" << endl;
break;
}
}
//5000组用例全部成功
cout << "success!" << endl;
system("pause");
return 0;
}