[C/C++]一些常用的随机函数实现

实现了一些比较常见的随机函数接口,包括从区间中随机、根据概率数组随机、根据置位情况随机等,希望有参考作用。

头文件:

#ifndef _RANDOM_FUNC_
#define _RANDOM_FUNC_

bool is_random_hit(int x, int n = 100);
int random_with_range(int a, int b);
void test_random_func();
int random_with_value_rate_array(int arr[][2], int count);
int random_with_rate_array(int arr[], int count);
int random_bit_off_index(int status, int n);
int random_bit_on_index(int status, int n);

#endif

实现文件:

#include "random_func.hpp"

#include <iostream>
#include<time.h>
#include<stdlib.h>
#include <string>
#include <cassert>
using namespace std;

/**
 * @brief 是否命中概率
 * @param x 概率为x/n
 * @param n 概率的基数
 * @return true表示命中概率
 */
bool is_random_hit(int x, int n)
{
	assert(n != 0);
	int r = rand() % n;
	return x < r;
}

/**
 * @brief 从一个区间中随机一个数
 * @param a 左界
 * @param b 右界
 * @return 随机的结果
 */
int random_with_range(int a, int b)
{
	//确保a < b
	if (a > b) {
		a ^= b ^= a ^= b;
	}

	//包含a和b
	int r = rand() % (b - a + 1);
	return r + a;
}

/**
 * @brief 根据概率数组,返回输出outid
 * @param arr 概率数组,会自动根据提供的数据计算概率,只支持整数
 * @param count 行的数量,即有多少个
 * @return 符合概率的数组下标
 */
int random_with_rate_array(int arr[], int count)
{
	// 默认的输出
	uint32_t outid = 0;

	uint32_t sum = 0; // 用于概率的统计
	int i;
	for (i = 0; i < count; i++) {
		sum += arr[i];
	}
	assert(sum != 0);
	int r = rand() % sum;

	sum = 0;
	for (i = 0; i < count; i++) {
		sum += arr[i];

		// 达到指定的概率
		if (r <= (int) sum) {
			outid = i;
			break;
		}
	}
	return outid;

}

/**
 * @brief 根据输出outid及概率的数组,返回输出outid
 * @param arr 概率数组,会自动根据提供的数据计算概率,只支持整数
 * @param count 行的数量,即有多少个
 * @return 符合概率的数组下标
 */
int random_with_value_rate_array(int arr[][2], int count)
{
	// 默认的输出
	uint32_t outid = arr[0][0];

	uint32_t sum = 0; // 用于概率的统计
	int i;
	for (i = 0; i < count; i++) {
		sum += arr[i][1];
	}
	assert(sum != 0);
	int r = rand() % sum;

	sum = 0;
	for (i = 0; i < count; i++) {
		sum += arr[i][1];

		// 达到指定的概率
		if (r <= (int) sum) {
			outid = arr[i][0];
			break;
		}
	}
	return outid;
}

/**
 * @brief 从指定数据status的前n位中随机出一个清位的位置
 * @param status 数据
 * @param n 前几位
 * @return 符合概率的位下标,从1开始
 */
int random_bit_off_index(int status, int n)
{
	assert(n > 0);
	int result = 0;
	int vec[32];
	int size = 0;
	for (int i = 0; i < n; ++i) {
		//找到清位
		if (!(status & (1 << i))) {
			vec[size++] = i + 1;
		}
	}
	if (size > 0) {
		result = vec[rand() % size];
	}
	return result;
}

/**
 * @brief 从指定数据status的前n位中随机出一个置位的位置
 * @param status 数据
 * @param n 前几位
 * @return 符合概率的位下标,从1开始
 */
int random_bit_on_index(int status, int n)
{
	assert(n > 0);
	int result = 0;
	int vec[32];
	int size = 0;
	for (int i = 0; i < n; ++i) {
		//找到置位的位置
		if ((status & (1 << i))) {
			vec[size++] = i + 1;
		}
	}
	if (size > 0) {
		result = vec[rand() % size];
	}
	return result;
}

void test_random_func()
{
	srand((int) time(0));

	cout << string(70, '=') << endl;
	cout << "is_random_hit" << endl;
	for (int i = 0; i < 10; ++i) {
		cout << i << ": " << is_random_hit(50) << endl;
	}

	cout << string(70, '=') << endl;
	cout << "ranged_random" << endl;
	for (int i = 0; i < 10; ++i) {
		cout << i << ": " << random_with_range(100, 50) << endl;
	}

	cout << string(70, '=') << endl;
	cout << "random_with_rate_array" << endl;
	int arr[] = { 50, 50, };
	int count = 2;
	for (int i = 0; i < 10; ++i) {
		cout << i << ": " << random_with_rate_array(arr, count) << endl;
	}

	cout << string(70, '=') << endl;
	cout << "random_with_value_rate_array" << endl;
	int arr2[][2] = { { 1, 50 }, { 2, 50 }, };
	count = 2;
	for (int i = 0; i < 10; ++i) {
		cout << i << ": " << random_with_value_rate_array(arr2, count) << endl;
	}

	cout << string(70, '=') << endl;
	cout << "random_bit_off_index" << endl;
	count = 3;
	for (int i = 0; i < 10; ++i) {
		cout << i << ": " << random_bit_off_index(8, count) << endl;
	}

	cout << string(70, '=') << endl;
	cout << "random_bit_on_index" << endl;
	count = 3;
	for (int i = 0; i < 10; ++i) {
		cout << i << ": " << random_bit_on_index(6, count) << endl;
	}

	cout << "---- end of test random func -----------" << endl;
}

某次的运行结果:

======================================================================
is_random_hit
0: 0
1: 1
2: 0
3: 1
4: 0
5: 0
6: 0
7: 1
8: 0
9: 1
======================================================================
ranged_random
0: 53
1: 52
2: 90
3: 51
4: 62
5: 85
6: 50
7: 54
8: 51
9: 84
======================================================================
random_with_rate_array
0: 1
1: 1
2: 1
3: 1
4: 1
5: 0
6: 1
7: 0
8: 0
9: 0
======================================================================
random_with_value_rate_array
0: 2
1: 1
2: 2
3: 2
4: 2
5: 2
6: 2
7: 1
8: 2
9: 2
======================================================================
random_bit_off_index
0: 3
1: 1
2: 1
3: 3
4: 3
5: 3
6: 3
7: 2
8: 3
9: 1
======================================================================
random_bit_on_index
0: 2
1: 3
2: 2
3: 3
4: 2
5: 3
6: 3
7: 3
8: 3
9: 2
---- end of test random func -----------


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

遗落尘污

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值