题:
给你一个字符串(可能有几亿个字符),给定一个特殊的字符'a',再给定一个可以产生0和1的随机数发生器,然后让你写一个函数,等概率地返回'a'的一个索引(就是'a'在字符串中的位置,比如字符串为 aaba,那么a的索引为{0, 1, 3},等概率地返回0、1或者3)
想:
最简单的想法:这个如果产生随机数,再把该随机数哈希到字符串长度范围内,再把得到的哈希值作为下标去看对应的字符满足不满足条件,满足条件则返回下标,不满足条件的话重新随机。缺点——如果满足条件的字符很少,那么完全不靠谱!
稍微容易想到的方法:遍历这个字符串,对满足条件的下标建立索引,然后根据索引大小产生随机数,随机访问索引,返回索引所对应的下标值。这个可以有,但是也有明显缺点——如果满足条件的字符很多,那么索引很大,占用大量存储!
最后就是完美的解答了:
答:
#include
<
sstream
>
#include < iostream >
#include < string >
#include < time.h >
using namespace std;
int given_rand()
{
return rand() % 2 ;
}
unsigned int my_rand()
{
int i, result;
for ( i = 0 , result = 0 ; i < 32 ; i ++ )
{
result <<= 1 ;
result += given_rand();
}
return result;
}
int main()
{
int index = 0 , cnt = 0 ;
stringstream strstring( " aabbbaaabbbbabbbbabbbbbbbbbbbaabbbbbbbbbbbbbbbbbbbbabaaaabbbbbbbbbbbbbbaaabbbbbbbbbbbb " );
int ret = 0 ;
char c;
srand(time(NULL));
while (strstring >> c)
{
index ++ ;
if (c == ' a ' ) {
++ cnt;
int rr = my_rand() % (cnt);
if (rr < 1 )
ret = index;
}
}
cout << ret;
return 0 ;
}
#include < iostream >
#include < string >
#include < time.h >
using namespace std;
int given_rand()
{
return rand() % 2 ;
}
unsigned int my_rand()
{
int i, result;
for ( i = 0 , result = 0 ; i < 32 ; i ++ )
{
result <<= 1 ;
result += given_rand();
}
return result;
}
int main()
{
int index = 0 , cnt = 0 ;
stringstream strstring( " aabbbaaabbbbabbbbabbbbbbbbbbbaabbbbbbbbbbbbbbbbbbbbabaaaabbbbbbbbbbbbbbaaabbbbbbbbbbbb " );
int ret = 0 ;
char c;
srand(time(NULL));
while (strstring >> c)
{
index ++ ;
if (c == ' a ' ) {
++ cnt;
int rr = my_rand() % (cnt);
if (rr < 1 )
ret = index;
}
}
cout << ret;
return 0 ;
}