平时编程时,总要搞点数组啥的,尤其是那些想要弄混随机数的时候。PHP有个shuffle()函数,看着简单好用,可实际用着就出问题了:它可能会让相邻的数字重复出现。这样一来,数据处理就不准确了,还可能影响后面的程序流程。为了解决这个问题,我试过好几个办法,其中两个效果挺好:一是用a-Hash算法,二是用标记和洗牌法。
a-Hash算法的原理与应用
用a-Hash这个算法之前,我就知道Hash有什么用。这个算法的牛逼之处就是,它可以给每样东西都算出个独一无二的哈希值。所以,在把数组搞乱之前,我就已经给每个元素算好了哈希值,然后把这些值和对应的元素记下来。就算shuffle()函数搞出来的元素有重复,因为哈希值都是独一无二的,所以我就能保证前后两个元素不会一样。虽然多花了点儿时间算哈希值,但是跟它带来的好处比起来,这点儿付出还是值得的。
标记和洗牌方法的实现
另外一个好用的办法就是用标签标记已经选过的地方。简单理解下,就是在开始洗牌前,给选好的索引做上记号。具体怎么搞?我弄了个小本子,专门记录哪些索引的东西已经被挑走了。然后每洗一次牌,我就看看有没有被标记的,把它们去掉。这样就算洗出来的牌有重复的,因为我提前处理掉了,最后也不会出现在结果里。这个方法可能有点麻烦,但是保证了结果的准确度!
<pre class='brush:php;toolbar:false;’>function shuffle_array_avoid_adjacent_duplicates(array &$array) {
$aHash = [];
$result = [];
foreach ($array as $key => $value) {
$ah = md5($value);
if (!isset($aHash[$ah])) {
$aHash[$ah] = true;
$result[] = $value;
}
}
shuffle($result);
return $result;
}
实战案例分析
在真正做事的时候,我碰到个得老倒腾数组顺序的问题。开始,我就随便用了那个啥shuffle()函数,然后问题来了:整出来的数组老是一堆连续一样的元素。又影响结果准头,还让我捉急。后来我想出了两个办法,一是a-Hash算法,二是标记再洗牌法,都挺有用滴。虽然这俩各有千秋,但我还是喜欢用第二种,因为它既能保持数据随机性,又不费劲儿。
解决问题后的感受
function shuffle_array_avoid_adjacent_duplicates(array &$array) { $marked = []; foreach ($array as $key => $value) { $marked[$key] = false; } while (count($marked)) { $key = array_rand($marked); $result[] = $array[$key]; unset($marked[$key]); unset($array[$key]); } shuffle($result); return $result; }
搞定这个问题之后,感觉真的是太爽了!代码运行得溜多了,还学到新技能。编程就是这样的,总有新的问题等你解决,解决的过程也是你学习成长的时候。我觉得自己很牛,能找到这么好的解决办法;同时,也对编程的无尽可能充满好奇。
对未来的展望
搞定了与旁边重复的元素困扰后,我发现这事儿还可以再优化下。以后,我想研究点更牛逼的算法和技巧,让代码质量和速度都飞起来!另外,我还想多交些同行朋友,大家一起进步!
$array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; $shuffled_array = shuffle_array_avoid_adjacent_duplicates($array); print_r($shuffled_array);
总结与问题
搞定PHP数组中的相邻重复元素问题,我用的是a-Hash算法和标记与洗牌花招,它们各有各的过人之处。大家伙儿在使用PHP弄数组时有啥好用的小绝活儿或者心得体会没?快来评论区分享一下,咱们共同进步希望我的分享能帮到你,觉得好的话别忘了给我点个赞并分享出去。
评论0