看到这个问题了:
随机取 m 个数(在 1 到 n 的范围之内),(m <= n),要求 m 个数没有重复。
有没有什么好的算法,时间复杂度和空间复杂度都很好。
// 随机取 m 个数(在 1 到 n 的范围之内),(m <= n),要求 m 个数没有重复。
// 有没有什么好的算法,时间复杂度和空间复杂度都很好。
// 方法 1 :生成一系列的随机数,重复的丢弃,利用 STL 的 set 可以方便地插入非重复元素。
// 缺点是浪费时间。
// 方法 2 :洗牌算法,用一个数组保存 1,2, 。。。,n 这些数,然后历遍数组,每次生成一个
// 随机数,作为下标,交换当前元素。然后取数组的前 m 个元素。缺点是浪费空间。
// 2007-07-23
// By rappizit@yahoo.com.cn
#include <iostream>
#include <set>
#include <vector>
#include <stdlib.h>
#include <time.h>
using namespace std;
void randomNexclusive(int n, int m)
{
if (n < m)
{
return;
}
int r;
set <int> s;
while (1)
{
r = rand () % n + 1;
s.insert (r); // set 底层实现是红黑树,插入复杂度是对数级的
if(s.size () == m)
{
break;
}
}
copy (s.begin (), s.end (), ostream_iterator <int> (cout, " "));
cout << endl;
}
void shuffle (int n, int m)
{
if (n < m)
{
return;
}
vector <int> v (n + 1);
int r, i;
for (i = 1; i <= n; i ++)
{
v [i] = i;
}
for (i = 1; i <= n; i ++)
{
r = rand () % n + 1;
swap (v [i], v [r]);
}
for (i = 1; i <= m; i++)
{
cout << v [i] << " ";
}
cout << endl;
}
void main ()
{ // 此句必不可少,否则生成相同序列,放到函数 randomNexclusive () 里面也不好
srand ((unsigned) time (NULL));
randomNexclusive (1000, 100);
cout << endl;
shuffle (1000, 100);
}
不过我认为这两个算法都还是能够满足一般要求的。
随机取 m 个数(在 1 到 n 的范围之内),(m <= n),要求 m 个数没有重复。
有没有什么好的算法,时间复杂度和空间复杂度都很好。
// 随机取 m 个数(在 1 到 n 的范围之内),(m <= n),要求 m 个数没有重复。
// 有没有什么好的算法,时间复杂度和空间复杂度都很好。
// 方法 1 :生成一系列的随机数,重复的丢弃,利用 STL 的 set 可以方便地插入非重复元素。
// 缺点是浪费时间。
// 方法 2 :洗牌算法,用一个数组保存 1,2, 。。。,n 这些数,然后历遍数组,每次生成一个
// 随机数,作为下标,交换当前元素。然后取数组的前 m 个元素。缺点是浪费空间。
// 2007-07-23
// By rappizit@yahoo.com.cn
#include <iostream>
#include <set>
#include <vector>
#include <stdlib.h>
#include <time.h>
using namespace std;
void randomNexclusive(int n, int m)
{
if (n < m)
{
return;
}
int r;
set <int> s;
while (1)
{
r = rand () % n + 1;
s.insert (r); // set 底层实现是红黑树,插入复杂度是对数级的
if(s.size () == m)
{
break;
}
}
copy (s.begin (), s.end (), ostream_iterator <int> (cout, " "));
cout << endl;
}
void shuffle (int n, int m)
{
if (n < m)
{
return;
}
vector <int> v (n + 1);
int r, i;
for (i = 1; i <= n; i ++)
{
v [i] = i;
}
for (i = 1; i <= n; i ++)
{
r = rand () % n + 1;
swap (v [i], v [r]);
}
for (i = 1; i <= m; i++)
{
cout << v [i] << " ";
}
cout << endl;
}
void main ()
{ // 此句必不可少,否则生成相同序列,放到函数 randomNexclusive () 里面也不好
srand ((unsigned) time (NULL));
randomNexclusive (1000, 100);
cout << endl;
shuffle (1000, 100);
}
不过我认为这两个算法都还是能够满足一般要求的。