实现了一些比较常见的随机函数接口,包括从区间中随机、根据概率数组随机、根据置位情况随机等,希望有参考作用。
头文件:
#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 -----------