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