【问题标题】:php 2000 unique random numbers between 1000 and 9999php 2000 1000 到 9999 之间的唯一随机数
【发布时间】:2014-06-16 11:44:24
【问题描述】:

我想生成 2000 个介于 1000 和 9999 之间的唯一随机数。 我正在做这样的事情,但它没有生成唯一的数字。

$numbers = array();             

// Loop while there aren't enough numbers
while (count($numbers) < 2000) {

    $random_number = rand(1000, 9999);

    if (!in_array($random_number, $numbers)) {             
       // This adds the number to the array      
       $numbers[] = 'A'.$random_number.'14';
    }

}

请帮忙。

【问题讨论】:

  • 删除数组中的所有数字,然后通过循环运行数组以检查新滚动的数字是否已经存在。
  • @kpp 我想你错过了in_array 部分。
  • 找到1234,然后添加A123414
  • @kpp 这已经发生了。
  • 唯一不等于随机。你可以生成像3,3,3,3,5,5,5 这样的数字,它仍然可以是一个随机序列。

标签: php random numbers


【解决方案1】:

与其运行许多随机尝试,对于像这样的小范围,我宁愿使用这种方法:

$candidates = range(1000, 9999);
shuffle($candidates);
$numbers = array_slice($candidates, 0, 2000);
$numbers = array_map(function ($number) { return "A{$number}14"; }, $numbers);

【讨论】:

  • 这比循环大量时间将 if 语句放在各处要好得多!不错!
  • 感谢@deceze 的解决方案,它确实非常简单和干净。再次感谢。
  • @Dieter 它当然具有 O(1) 的优势,而不是具有无法确定的运行时甚至可能产生无限循环... :)
  • @deceze 是的!我喜欢! :)
【解决方案2】:

你检查一个号码是否存在,比如4567,但你添加了'A456714',所以你找不到这个号码。

你可以这样修复它:

$numbers = array();             

// Loop while there aren't enough numbers
while (count($numbers) < 2000) {

    $random_number = rand(1000, 9999);

    $code = 'A'.$random_number.'14';

    if (!in_array($code, $numbers)) {             
       // This adds the number to the array      
       $numbers[] = $code;
    }

}

我必须说,deceze 的解决方案也非常好(实际上更好)。不同之处在于,在他的解决方案中,您根本不需要检查任何双数,因此大多数时候它可能会更快。

缺点是您将拥有一个包含 9000 个数字的相对较大的数组。对于这种特定情况,他的解决方案可能会更好,但是如果您选择较少数量的随机数,或者从更大的范围内,这个(您自己的)解决方案可能会更好。如果您想从range(100, 1000000) 中选择 100 个随机数,那么这种解决方案可能会更好,因为选择双数的机会非常小并且检查它非常轻量级。

很难说引爆点在哪里,但就你目前的情况,我会选择他的。

【讨论】:

  • 该解决方案的缺点是执行时间不可预测(您无法真正确定生成这 2k 个数字需要多少时间),而 Decease 的解决方案具有线性执行时间。
【解决方案3】:

与其检查数组是否已经存在,不如试试这个:

<?php

$numbers=array();

while (count($numbers)<2000)
{
    $numbers['A'.rand(1000,9999).'14']=true;
}

$unique=array_keys($numbers);

echo print_r($unique,true).PHP_EOL;

它使用数组键是唯一的这一事实来消除数组检查。我猜想计算数组中元素的数量要快得多

【讨论】:

    【解决方案4】:

    这是因为您将 A 和 14 添加到要放入数组 $numbers 中的每个数字中。 因此,您生成的每个数字的下一个循环都不会有任何相同的数字..

    对不起,我的英语不好..

    【讨论】:

      【解决方案5】:

      random.org API:

      $numbers = explode(PHP_EOL,
          file_get_contents(
              'http://www.random.org/integers/?num=2000&min=1000&max=9999&col=1&base=10&format=plain&rnd=new'
          )
      );
      
      
      $numbers = array_map(function($v) {
          return 'A' . $v . '14';
      }, $numbers);
      

      【讨论】:

      • 这样一个小问题的 HTTP 调用开销...?对随机性的要求在这里更好。 :P 如果我不信任默认实现,我宁愿基于/dev/random 实现我自己的shuffle
      • 很有趣,但是获取和解析结果已经比“脚本内”实现更多的代码,并且它引入了执行外部请求和必须解析大结果字符串的开销。当然,你引入了不必要的外部依赖。
      • 您对开销的看法都是正确的,我什至不确定我为什么发布这个答案;-S 我自己使用/dev/urandom 流..
      【解决方案6】:
      function random_in_rang($min, $max, $count)
      {
          $numbers = array();
          for($i=0; $i<$count; $i++)
          {
              //decrease range after adding a new random value
              $rnd = rand($min, $max-$count);
              //new value should be unique
              while(isset($numbers[$rnd])) $rnd++;
          }
          return array_keys($numbers);
      }
      

      【讨论】:

        【解决方案7】:

        一种更有效的方式(用于速度和内存使用)大范围:

        function get_unique_random_numbers($min,$max,$count) {
            $numbers = array();
            while( count($numbers) < $count ) {
                  $numbers["A".mt_rand($min,$max)."14"] = 1;
            }
            return array_keys($numbers);
        }
        
        $numbers = get_unique_random_numbers(0,90000000,20000);
        // < 0.X seconds
        

        这种方法在($max-$min) &gt;&gt; $count时效率更高。 但是($max-$min) ~ $count 时速度很慢。 ($max-$min) &lt; $count 时会无限循环。

        所以要小心。 :) 最终在开始循环之前进行检查。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-27
          • 2011-01-23
          • 2012-02-02
          • 2015-11-10
          相关资源
          最近更新 更多