通常情况下在刷OJ时,由于测试用例有限,我们无法保证在大样本数据下结果依然成立,那么用有没有一种方式可以保证在大样本用例下仍然可以判断我们的方法依然正确?--对数器
在使用对数器之前,我们必须保证有一种完全正确的方法作为参照物,通过比对新方法和完全正确的方法在大样本下的运行是否一致。
关于对数器的coding思路:利用随机数的生成,生成随机大小和范围的数组或其他数据结构的用例,对C语言来讲就是利用srand函数。下面以经典的插入排序和冒泡排序为例具体解释:
插入排序:
void insert_sort(int* nums, int numsSize)
{
for (int i = 0; i < numsSize-1; i++)
{
for (int j = i + 1; j - 1 > 0 && nums[j] < nums[j - 1]; j--)
{
swap(&nums[j], &nums[j - 1]);
}
}
}
冒泡排序:
void bob_sort(int* nums, int numsSize)
{
for (int i = 0; i < numsSize - 1; i++)
{
for (int j = i+1; j < numsSize; j++)
{
if (nums[j] < nums[i])
{
swap(&nums[j], &nums[i]);
}
}
}
}
对数器:
1.首先是生成固定大小和范围的随机数组:
int *generateNums(int *nums ,int max,int range,int testTimes)
{
srand((unsigned int)time(NULL));
for (int j = 0; j < max; j++)
{
nums[j] = rand() % range + 1;
}
return nums;
}
2.判断两数组是否相等,用于排序后对比两种方法的结果是否一致,也就是新的方法是否正确,如下:
bool is_equal(int* nums1, int* nums2,int max)
{
for (int i = 0; i < max; i++)
{
if (nums1[i] == nums2[i])
{
return true;
}
}
return false;
}
3.由于C语言的随机数生成本质是利用srand函数,其中种子作为参数,这里的种子为time(NULL),使得每次运行的结果都不一样。所以我们需要写一个copy函数,用于随机生成的两个数组保持一致。代码如下:
int *copy_nums(int* nums1, int max)
{
int* nums2 = (int*)malloc(max * sizeof(int));
if (nums2 == NULL)
{
for (int i = 0; i < max; i++)
{
nums2[i] = nums1[i];
}
}
return nums2;
}
4.主函数的实现:
int main()
{
int max = 6;
int range = 10;
int testTime = 5000;
int successedCount = 0;
int errorCount = 0;
for (int i = 0; i < testTime; i++)
{
int nums1[6];
int nums2[6];
generateNums(nums1,6, 10, 5000);
generateNums(nums2, 6, 10, 5000);
//copy_nums(nums1, max);
bob_sort(nums1, max);
insert_sort(nums2, max);
if (is_equal(nums1, nums2, max))
{
successedCount++;
}
else
errorCount++;
}
if (errorCount == 0)
printf("allsucceed");
else
printf("exiterror");
return 0;
}