我需要从600k到2000k生成一个大的随机数列表,但是 列表不能有重复。
我目前的'实施'如下:
<?php
header('Content-type: text/plain');
$startTime = microtime(true);
$used = array();
for ($i=0; $i < 600000; ) {
$random = mt_rand();
//if (!in_array($random, $used)) {
$used[] = $random;
$i++;
//}
}
$endTime = microtime(true);
$runningTime = $endTime - $startTime;
echo 'Running Time: ' . $runningTime;
//print_r($used);
?>
如果我保持in_array
测试评论,处理时间大约是1秒,那么
mt_rand
调用和used
数组填充相对“便宜”但是当我取消注释时
in_array测试坏事发生了! (我只是在等待 - 已经超过10分钟 - 脚本终止......)
所以我正在寻找重复检测方面或生成部分的替代品(如何生成随机数而不会有重复的风险)
我愿意接受任何建议。
答案 0 :(得分:15)
对于快速/肮脏的解决方案,使用/检查数组键是否可以提高速度?
$used = array();
for ($i = 0; $i < 600000; ) {
$random = mt_rand();
if (!isset($used[$random])) {
$used[$random] = $random;
$i++;
}
}
$used = array_values($used);
答案 1 :(得分:5)
in_array
要求在最坏的情况下搜索整个数组,这意味着线性成本( O ( n ))。但是使用数组密钥 - 密钥 - 成本是恒定的( O (1)),因为数组访问的成本总是不变的。
答案 2 :(得分:2)
你可以做一些像这样的事情
$random = mt_rand();
$array = range($random, $random + 600000);
$array = shuffle($array);
这将创建一个首先按顺序排列的数组,但随后它会对数组进行洗牌,因此值将是随机的。没有碰撞! :d
答案 3 :(得分:1)
如果你仍然进行循环,如果你不需要超过600000,为什么你会检查它们,为什么不直接将$ i附加到$ random。完成。不够随便?
for ($i = 0; $i < 600000; $i++)
{
$yourArray[] = mt_rand() . $i;
}
此外还有数组函数array_unique,它可以从数组中删除重复值。