服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - c++ 对数器实现示例

c++ 对数器实现示例

2021-12-15 14:21机巧的胖子 C/C++

对数器用于在自己的本地平台验证算法正确性,本文详细的介绍了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)可以得到结果,如下图所示,所以我们默认已经覆盖了所有情况,我们的算法是正确的。

c++ 对数器实现示例

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

c++ 对数器实现示例

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

c++ 对数器实现示例

 

完整代码

附完整代码:

// 对数器.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++ 对数器内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/wcb425499094/article/details/119654754

延伸 · 阅读

精彩推荐
  • C/C++c/c++实现获取域名的IP地址

    c/c++实现获取域名的IP地址

    本文给大家汇总介绍了使用c/c++实现获取域名的IP地址的几种方法以及这些方法的核心函数gethostbyname的详细用法,非常的实用,有需要的小伙伴可以参考下...

    C++教程网10262021-03-16
  • C/C++使用C++制作简单的web服务器(续)

    使用C++制作简单的web服务器(续)

    本文承接上文《使用C++制作简单的web服务器》,把web服务器做的功能稍微强大些,主要增加的功能是从文件中读取网页并返回给客户端,而不是把网页代码...

    C++教程网5492021-02-22
  • C/C++C语言main函数的三种形式实例详解

    C语言main函数的三种形式实例详解

    这篇文章主要介绍了 C语言main函数的三种形式实例详解的相关资料,需要的朋友可以参考下...

    ieearth6912021-05-16
  • C/C++OpenCV实现拼接图像的简单方法

    OpenCV实现拼接图像的简单方法

    这篇文章主要为大家详细介绍了OpenCV实现拼接图像的简单方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    iteye_183805102021-07-29
  • C/C++深入C++拷贝构造函数的总结详解

    深入C++拷贝构造函数的总结详解

    本篇文章是对C++中拷贝构造函数进行了总结与介绍。需要的朋友参考下...

    C++教程网5182020-11-30
  • C/C++C语言实现双人五子棋游戏

    C语言实现双人五子棋游戏

    这篇文章主要为大家详细介绍了C语言实现双人五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    两片空白7312021-11-12
  • C/C++c/c++内存分配大小实例讲解

    c/c++内存分配大小实例讲解

    在本篇文章里小编给大家整理了一篇关于c/c++内存分配大小实例讲解内容,有需要的朋友们可以跟着学习参考下。...

    jihite5172022-02-22
  • C/C++关于C语言中E-R图的详解

    关于C语言中E-R图的详解

    今天小编就为大家分享一篇关于关于C语言中E-R图的详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看...

    Struggler095962021-07-12