Quantcast
Channel: CSDN博客推荐文章
Viewing all articles
Browse latest Browse all 35570

洗牌算法多种形式

$
0
0

洗牌算法直观的来说,是将一幅有序的扑克牌经过处理后变成乱序的。这个处理的过程就是洗牌算法了,当然这里的扑克牌也许是其他的数据等等,算法要保证乱序后的数据和之前的一模一样,只是顺序不同而已。下面就针对不同形式的洗牌算法给出代码。


有54张牌,乱序存储在一个整型数组中arr[54]。一副牌就用1,,,54这54个数字代替。

//从无到有随机生成一副牌序
void MyShuffle_NonToSome(int arr[] ,int num)
{
	srand(time(NULL));
	int pos,temp = 0;
	memset(arr,0,sizeof(int) * num);

	for (int idx = 1; idx <= 54; idx++)
	{
		do 
		{
			pos = rand() % num;
		} while (arr[pos] != 0);
		arr[pos] = idx;
	}
}

这种方式下,首先是两层循环的嵌套,本来就降低了效率,而且随着数组中数据的增多里层循环执行的次数也越来越多。

rand()的定义:


srand()的定义:




针对一个已经给出的有序的序列,可以采用随机交换两个数组元素的方式实现乱序。至于交换的次数由个人来定,交换的次数越多就越接近乱序,就越有效。

//基于N次交换的随机算法,固定循环次数
void MyShuffle_Ns_Swap(int arr[], int num)
{
	int pos1,pos2;
	int temp = 0;
	srand(time(NULL));
	for (int idx = 0; idx < num; idx++)
	{
		pos1 = rand() % num;
		pos2 = rand() % num;
		if (pos1 != pos2)
		{
			temp = arr[pos1];
			arr[pos1] = arr[pos2];
			arr[pos2] = temp;
		}
	}
}
这种方法循环次数一定,交换次数一般情况下就是数据的个数,简单明朗


还有一种和这个类似,第一次在0到53之间生成一个随机数randomNum,将其(arr[randomNum])作为下标和数组最后一个(arr[53])互换位置;然后缩小随机范围,在0到52之间随机一个数字将其作为下标arr[randomNum]和arr[52]互换位置,经过54次交换也可以达到乱序效果。

//从后往前缩小随机范围,将每一次随机到的值以此从后往前存放,固定循环次数
void MyShuffl_CutRange(int arr[], int num)
{
	//初始化随机数生成器种子
	srand(time(NULL));
	int pos,temp = 0;
	unsigned int size = num;
	for (int idx = num-1; idx >= 0; idx--)
	{
		pos = rand() % size--;

		if (pos != idx)
		{
			temp = arr[pos];
			arr[pos] = arr[idx];
			arr[idx] = temp;
		}
	}
}


作者:ZLhy_ 发表于2013-2-24 0:54:23 原文链接
阅读:127 评论:0 查看评论

Viewing all articles
Browse latest Browse all 35570

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>