1. 产生n个不重复的随机数字,范围是[0, n)。基本思想:有序数据的随机交换。
static int randint(int l, int u)
{ return l + rand() % (u-l+1);
}
/* generate n distinct random integer in range [0, n)
* the implementation depends on a global varible
* int gRawDataSet[DATA_SET_SIZE];
*
* generate random index then replace the current element
* with that one.
*/
static void gen_distinct_random(int n)
{
//printf("%d\n", n);
int i;
for (i = 0; i < n; i++)
{
gRawDataSet[i] = i;
}
for (i = 0; i < n; i++)
{
int idx = randint(i, n - 1); //printf("idx = %d \n", idx);
int t = gRawDataSet[idx];
gRawDataSet[idx] = gRawDataSet[i];
gRawDataSet[i] = t;
printf("%d ", gRawDataSet[i]);
}
printf("\n");
}
2.检验产生的随机数字序列是否有序? 是否存在重复元素?序列是否有序的判断是一个十分直观的问题,是否存在重复元素的判断就要复杂一些了。可以采用的方法有两类。第一类是采用先排序将重复元素集中再进行检测的方式。第二类是借助额外的数据结构。C++ STL中的set就是一个很好的结构,短短的几行代码就能够实现功能。
int sorted(int n)
{
int i;
for (i = 0; i < n - 1; i++)
{
if (gRawDataSet[i] > gRawDataSet[i + 1]) return 0;
}
return 1;
}
/* take advantage of C++ STL set.insert() to check the duplicate
* reference location:
* http://www.cplusplus.com/reference/set/set/insert/
*
*/
int duplicated(int n)
{
set<int> s;
pair<set<int>::iterator, bool> ret;
int i;
for (i = 0; i < n; i++)
{
ret = s.insert(gRawDataSet[i]);
if (ret.second == false) return 1; // the duplicate exist!
}
return 0;
}
3.从[0, n)的n个元素的有序序列中随机选取m个有序的元素构成一个新的序列。要求保证每个元素被选中的概率是相等的。
/* generate m distinct sorted random number in [0, n)
* rand(): Returns a pseudo-random integral number in the range 0 to RAND_MAX
* This number is generated by an algorithm that returns a sequence of
* apparently non-related numbers each time it is called.
* This algorithm uses a seed to generate the series, which should be initialized
* to some distinctive value using function srand.
* http://www.cplusplus.com/reference/cstdlib/rand/?kw=rand for details.
*
* prototype : double difftime (time_t end, time_t beginning);
* Calculates the difference in seconds between beginning and end.
* this is an inexact method to meter the performance!
*/
void gen_sorted_randint(int n, int m)
{
int i, j;
LOG_I("+[ %s ]\n", __FUNCTION__);
#ifdef PERFORMANCE_METER
time_t tm1, tm2;
time(&tm1); /* get current time */
#endif
j = 0;
//srand(time(NULL)); /* initialize random seed */
for (i = 0; i < n; i++)
{
if (rand() % (n - i) < m)
{
gRawDataSet[gDataSetCount++] = i;
m--;
printf("%4u ", i);
if (++j % 8 == 0) printf("\n");
}
}
printf("\n");
#ifdef PERFORMANCE_METER
time(&tm2);
double seconds = difftime(tm2, tm1); /* return double */
LOG_D("[Run time] %.lf s!\n", seconds);
#endif
LOG_I("-[ %s ]\n", __FUNCTION__);
}
基本思想:按照有序地方式逐个遍历每个元素,
采用随机的方式确定该元素是否加入到新的序列中去。上面的代码中关键部分只有3行。
参考资料
rand()接口的相关介绍 http://www.cplusplus.com/reference/cstdlib/rand/?kw=rand点击打开链接
set.insert()相关介绍 http://www.cplusplus.com/reference/set/set/insert/点击打开链接
programming pearls http://netlib.bell-labs.com/cm/cs/pearls/index.html点击打开链接