从n中取出m个不重复的数

辅助函数,randint(i,j)获取[i,j]的一个随机数

int randint(int i , int j)
{
	return rand()%(j-i+1)+i;
}

方法1:

从n个中取m个,当前这个数被取出的概率为n/m,即if(rand() % n < m)就被取出。

void genKnuth(unsigned int n , unsigned int m)
{
	int remain = n;
	int unselect = m;

	for (int i = 0;i<n;++i)
	{
		if (rand()%remain < unselect)
		{
			std::cout<<i<<std::endl;
			--unselect;
		}
		--remain;
	}
}

剩下remain个数,还有unselect个未取,那么当前这个数被取出的概率为unselect/remain。要说的是从100个取20个数,这个方法必定能取出20个数。如果当前取出的以足20个,那么unselect=0,那么后面的所有数都不会被取。如果未满20个,那么后面的都有一定的概率被取到,极端情况就是前面都没有被取到,那么后面的数被取到的概率会越来越大,直到被取出的概率为1为止。

方法2:

向set中插入不重复的m个数即可。

void genSet(unsigned int n , unsigned int m)
{
	std::set<int> s;
	while(s.size() < m)
		s.insert(rand() % n);

	for (int i : s)
	{
		std::cout<<i<<std::endl;
	}
}

set的特点是如果有了数字t,那么再插入数字t,也只是只有一个数字t。这点和MultiSet不同。不知道的可以学习下STL。

方法3:

把牌洗乱,然后抽出20个即可。

void genShuf(int n , int m)
{
	int * x = new int[n];
	for (int i = 0 ; i < n ; ++i)
	{
		x[i] = i;
	}
	int j;
	for (int i = 0 ; i < m ; ++i)
	{
		j = randint(i , n-1);
		if (i != j)
		{
			swap(x[i] , x[j]);
		}
	}
	sort(x,x+m);
	for (int i = 0 ; i < m ;++i)
	{
		std::cout<<x[i]<<std::endl;
	}
	delete []x;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值