对数器的作用
对数器用于在自己的本地平台验证算法正确性,用于算法调试,无需online judge。
好处:
- 没找到线上测试的online judge,则可以使用对数器。
- 大数据样本出错时,快速找到出错地方。
- 贪心策略使用,直接验证是否正确
对数器的实现代码
- 首先需要有一个你想要测试的方法,本文利用归并排序算法举例。归并算法代码如下:
class Solution {
public:
static int reversePairs(vector<int>& nums) {
auto L = 0;
auto R = nums.size() - 1;
auto res = 0;
mergesort(nums, L, R);
return res;
}
static void mergesort(vector<int>& nums, int L, int R)
{
if (L >= R)
{
return;
}
auto mid = (L + ((R - L) >> 1));
mergesort(nums, L, mid);
mergesort(nums, mid + 1, R);
merge(nums, L, mid, R);
}
static void merge(vector<int>& nums, int L, int mid, int R)
{
vector<int> tmp(R - L + 1);
auto pos = 0;
auto Lp = L;
auto Rp = mid + 1;
while ((Lp <= mid) && (Rp <= R))
{
tmp[pos++] = (nums[Lp] < nums[Rp]) ? nums[Lp++] : nums[Rp++];
}
while (Lp <= mid)
{
tmp[pos++] = nums[Lp++];
}
while (Rp <= R)
{
tmp[pos++] = nums[Rp++];
}
copy(nums, tmp, L, R);
}
static void copy(vector<int>& nums, vector<int>& tmp, int L, int R)
{
auto pos = 0;
for (auto i = L; i <= R; i++)
{
nums[i] = tmp[pos++];
}
}
};
- 准备一个随机数组(样本)生成器,该示例选择size为10,value为30,代码如下:
vector<int> generateRandomVector(int size, int value)
{
srand((int)time(NULL));
vector<int> result(rand() % (size + 1));
for (auto i = 0; i < result.size(); i++)
{
result[i] = rand() % (value + 1);
}
return result;
}
- 大样本测试,同时还需要准备一个绝对正确的方法,这里用algorithm头文件中的sort函数进行排序,同时测试次数应该尽量大,从而覆盖尽可能所有的实例,如果没有自己算法和绝对正确的算法的结果的比对方法,还需要自己编写结果的比对方法,判断结果是否正确(这里vector重载了比较运算符,直接使用即可),代码如下:
int main()
{
auto test_time = 50000;
auto size = 10;
auto value = 30;
auto if_accept = true;
for(auto i = 0; i < test_time; i++)
{
vector<int> nums(generateRandomVector(size, value));
vector<int> nums1(nums);
vector<int> nums2(nums);
sort(nums1.begin(), nums1.end());
Solution::reversePairs(nums2);
if(nums1 != nums2)
{
if_accept = false;
for(auto c: nums)
{
cout << c << " ";
}
break;
}
}
cout << (if_accept ? "nice!\n" : "false!\n");
}
运行上述代码,由于我们测试样本次数为50000次,而样本量本身比较小(size = 10, value = 30)可以得到结果,如下图所示,所以我们默认已经覆盖了所有情况,我们的算法是正确的。
将归并排序算法改为降序排列,重新运行可得:
由于每次设定的种子源是随机的,所以每次运行可以得到不同的序列。
完整代码
附完整代码:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
static int reversePairs(vector<int>& nums) {
auto L = 0;
auto R = nums.size() - 1;
auto res = 0;
mergesort(nums, L, R);
return res;
}
static void mergesort(vector<int>& nums, int L, int R)
{
if (L >= R)
{
return;
}
auto mid = (L + ((R - L) >> 1));
mergesort(nums, L, mid);
mergesort(nums, mid + 1, R);
merge(nums, L, mid, R);
}
static void merge(vector<int>& nums, int L, int mid, int R)
{
vector<int> tmp(R - L + 1);
auto pos = 0;
auto Lp = L;
auto Rp = mid + 1;
while ((Lp <= mid) && (Rp <= R))
{
tmp[pos++] = (nums[Lp] < nums[Rp]) ? nums[Lp++] : nums[Rp++];
}
while (Lp <= mid)
{
tmp[pos++] = nums[Lp++];
}
while (Rp <= R)
{
tmp[pos++] = nums[Rp++];
}
copy(nums, tmp, L, R);
}
static void copy(vector<int>& nums, vector<int>& tmp, int L, int R)
{
auto pos = 0;
for (auto i = L; i <= R; i++)
{
nums[i] = tmp[pos++];
}
}
};
vector<int> generateRandomVector(int size, int value)
{
srand((int)time(NULL));
vector<int> result(rand() % (size + 1));
for (auto i = 0; i < result.size(); i++)
{
result[i] = rand() % (value + 1);
}
return result;
}
int main()
{
auto test_time = 50000;
auto size = 10;
auto value = 30;
auto if_accept = true;
for(auto i = 0; i < test_time; i++)
{
vector<int> nums(generateRandomVector(size, value));
vector<int> nums1(nums);
vector<int> nums2(nums);
sort(nums1.begin(), nums1.end());
Solution::reversePairs(nums2);
if(nums1 != nums2)
{
if_accept = false;
for(auto c: nums)
{
cout << c << " ";
}
break;
}
}
cout << (if_accept ? "nice!\n" : "false!\n");
}
|