c++ 对数器实现示例

 更新时间:2021年08月13日 16:11:31   作者:机巧的胖子  
对数器用于在自己的本地平台验证算法正确性,本文详细的介绍了c++ 对数器实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

对数器的作用

对数器用于在自己的本地平台验证算法正确性,用于算法调试,无需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));
        //auto mid = (R + L) / 2;
        //左右序列分别排序
        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++];
        }

    	//将排序好部分拷贝至nums数组
        copy(nums, tmp, L, R);
        //nums = tmp;
    }

	//部分数组拷贝函数
    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,代码如下:

//函数名:generateRandomVector
//函数功能描述:随机数组(样本)生成器
//函数参数: size    生成数组最大尺寸
//         value   数组每个元素的最大值
//返回值:  vector<int> 生成的数组
//for test
vector<int> generateRandomVector(int size, int value)
{
    //time 函数返回从 1970 年 1 月 1 日午夜开始到现在逝去的秒数,因此每次运行程序时,它都将提供不同的种子值。
    srand((int)time(NULL));//为随机数生成器产生随机种子
    //分配随机大小的数组,产生随机数的范围公式number = (rand()%(maxValue - minValue +1)) + minValue;
    vector<int> result(rand() % (size + 1));
    for (auto i = 0; i < result.size(); i++)
    {
        result[i] = rand() % (value + 1);
    }

    return result;

}

大样本测试,同时还需要准备一个绝对正确的方法,这里用algorithm头文件中的sort函数进行排序,同时测试次数应该尽量大,从而覆盖尽可能所有的实例,如果没有自己算法和绝对正确的算法的结果的比对方法,还需要自己编写结果的比对方法,判断结果是否正确(这里vector重载了比较运算符,直接使用即可),代码如下:

//大样本测试
//函数名:main
//函数功能描述:大样本测试
//函数参数: size    生成数组最大尺寸
//         value   数组每个元素的最大值
//返回值:  vector<int> 生成的数组
//for test
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);

		//判断两个向量是否相同,vector类已经重载了比较运算符,不用自己实现,不相同说明算法不正确
		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)可以得到结果,如下图所示,所以我们默认已经覆盖了所有情况,我们的算法是正确的。

在这里插入图片描述

将归并排序算法改为降序排列,重新运行可得:

在这里插入图片描述

由于每次设定的种子源是随机的,所以每次运行可以得到不同的序列。

在这里插入图片描述

完整代码

附完整代码:

// 对数器.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#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));
        //auto mid = (R + L) / 2;
        //左右序列分别排序
        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++];
        }

    	//将排序好部分拷贝至nums数组
        copy(nums, tmp, L, R);
        //nums = tmp;
    }

	//部分数组拷贝函数
    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++];
        }
    }
};


//准备一个随机数组(样本)生成器
//函数名:generateRandomVector
//函数功能描述:随机数组(样本)生成器
//函数参数: size    生成数组最大尺寸
//         value   数组每个元素的最大值
//返回值:  vector<int> 生成的数组
//for test
vector<int> generateRandomVector(int size, int value)
{
    //time 函数返回从 1970 年 1 月 1 日午夜开始到现在逝去的秒数,因此每次运行程序时,它都将提供不同的种子值。
    srand((int)time(NULL));//为随机数生成器产生随机种子
    //分配随机大小的数组,产生随机数的范围公式number = (rand()%(maxValue - minValue +1)) + minValue;
    vector<int> result(rand() % (size + 1));
    for (auto i = 0; i < result.size(); i++)
    {
        result[i] = rand() % (value + 1);
    }

    return result;

}

//大样本测试
//函数名:main
//函数功能描述:大样本测试
//函数参数: size    生成数组最大尺寸
//         value   数组每个元素的最大值
//返回值:  vector<int> 生成的数组
//for test
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);

		//判断两个向量是否相同,vector类已经重载了比较运算符,不用自己实现,不相同说明算法不正确
		if(nums1 != nums2)
		{
            if_accept = false;
			//输出结果不相等的原始向量
			for(auto c: nums)
			{
                cout << c << " ";
			}
			break;
		}
		
	}
	

	//输出结果
    cout << (if_accept ? "nice!\n" : "false!\n");
    
}

到此这篇关于c++ 对数器实现示例的文章就介绍到这了,更多相关c++ 对数器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MFC程序设计常用技巧汇总

    MFC程序设计常用技巧汇总

    这篇文章主要介绍了MFC程序设计常用技巧,实例汇总了MFC程序设计中常见的问题与解决方法,非常具有实用价值,需要的朋友可以参考下
    2015-05-05
  • c++ 单线程实现同时监听多个端口

    c++ 单线程实现同时监听多个端口

    这篇文章主要介绍了c++ 单线程实现同时监听多个端口的方法,帮助大家更好的理解和学习使用c++,感兴趣的朋友可以了解下
    2021-03-03
  • C/C++从零开始的cmake教程

    C/C++从零开始的cmake教程

    今天小编就为大家分享一篇关于C/C++从零开始的cmake教程,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-10-10
  • C++中指针和引用的区别详解

    C++中指针和引用的区别详解

    这篇文章主要介绍了C++中指针和引用的区别详解的相关资料,需要的朋友可以参考下
    2017-02-02
  • 浅析C/C++中sort函数的用法

    浅析C/C++中sort函数的用法

    做项目的时候,排序是一种经常要用到的操作。如果每次都自己写个冒泡之类的O(n^2)排序,不但程序容易超时,而且浪费宝贵的时间,还很有可能写错。STL里面有个sort函数,可以直接对数组排序,复杂度为n*log2(n)。
    2014-09-09
  • C++ OpenCV实现二维码检测功能

    C++ OpenCV实现二维码检测功能

    这篇文章主要介绍了如何利用C++ OpenCV实现二维码检测功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-01-01
  • C++ Boost.Range与Adapters库使用详解

    C++ Boost.Range与Adapters库使用详解

    这篇文章主要介绍了C++ Boost.Range与Adapters库使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-11-11
  • C++中的friend友元函数详细解析

    C++中的friend友元函数详细解析

    友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样
    2013-09-09
  • VSCode 配置C++开发环境的方法步骤

    VSCode 配置C++开发环境的方法步骤

    这篇文章主要介绍了VSCode 配置C++开发环境的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • 深入理解C++中的new/delete和malloc/free动态内存管理及区别介绍

    深入理解C++中的new/delete和malloc/free动态内存管理及区别介绍

    这篇文章主要介绍了深入理解C++中的new/delete和malloc/free动态内存管理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09

最新评论