【问题标题】:unique combination of arrays数组的独特组合
【发布时间】:2013-07-25 14:21:52
【问题描述】:

我想编写一个函数,每次从一个范围调用它直到重置它,它都会返回随机唯一的对数。 像这样的:

function randomUniquePairs($ranges, $reset = false){
   if ($reset === false){
      // some code for reseting
   }
   /*
     some code for creating random unique pair numbers
   */
   return $result;  
} 

randomUniquePairs(range(1,10), range(1,20));
/*
  this function returns for example:
   array(2,9)
*/
randomUniquePairs(range(1,10), range(1,20));
/*
  this function returns for example:
   array(5,19)
*/

randomUniquePairs(range(1,10), range(1,20));
/*
  this function returns for example:
   array(5,19)
*/
 //this function returns random unique pairs until we pass reset paramer true

我尝试了两种方法:

1) 其中一个是制作所有可能的对,然后从它们中随机选择,但效率非常低,因为如果范围如此之宽,则会消耗大量内存。 代码:

  class a {
    private $asqar;

    function __construct() ($range) {

        // cycle for ranges
        foreach ($range[0] as  $v1) {
            foreach ($range[1] as $v2) {
                $asqar[] =  array(
                    $v1,
                    $v2,
                );
            }
        }
    }

    function randomUniquePairs($reset = false){

        if ($reset === true){
           $this->asgar = array();
        }

        $rndKey = array_rand($this->asgar);
        $result = $this->asqar[$rndkey];
        unset($this->asqar[$rndkey]);
        return $result;
    }
}

$c = new a(range(1,10), range(1,20));
$c->randomUniquePairs();

2)second 是编写一个从这些范围产生一对的函数,然后将其存储在一个变量中,每次该函数在产生一对之后调用时,它都会检查该对是否在递归调用函数之前产生,它会继续直到它产生独特的一对。 这段代码:

class a{ 

    private $__uniqueVariables = array();

    public function randomUniquePairs($range, $reset = false) {

        if ($reset === true){
       $this->__uniqueVariables = array();
    }

    // cycle for each value
    foreach ($range as $value) {

        // shuffle
        shuffle($value);

        // selected id
        $selectedId[] = $value[0];
    }

    // check for selected variable
    if (in_array($rndUnqNum, $this->__uniqueVariables)) {

        // return for try again
        return $this->uniqueVariable($range);
    }

    // added to current unique variables
    $this->__uniqueVariables[] = $rndUnqNum;

    // return
    return $rndUnqNum;
}

}

但这有一个问题,有时会抛出Fatal error: Maximum function nesting level of '100' reached

我想要更好的算法。

【问题讨论】:

  • 当我尝试此代码时,我收到此错误:致命错误:在第 35 行的 test.php 中调用未定义的方法 a::b()。b(array... 做什么?

标签: php arrays unique combinations


【解决方案1】:

即使在大范围内,这似乎也做得很好:

rand() function 是获得指定范围内的随机整数的好方法,无需构造或操作值数组,如您上面的示例所示。

更新我添加了一个停止情况(当历史记录等于或大于最大可能的唯一对时,它返回一个空数组)。随意更改该代码以自动重置范围。

<?php
class c {

    function c($min_X,$max_X,$min_Y,$max_Y) {
        $this->setRange($min_X,$max_X,$min_Y,$max_Y);
    }

    function getRandUniquePair($reset = false) {
        if ($reset) {
            $this->__history = array();
        }

        if (count($this->__history) >= $this->__max_pairs) {
            return array();
        }

        $candidate = array(rand($this->__range[0],$this->__range[1]),rand($this->__range[2],$this->__range[3]));

        if (in_array($candidate,$this->__history)) {
            return $this->getRandUniquePair();
        }

        $this->__history[] = $candidate;

        return $candidate;
    }

    function setRange($min_X,$max_X,$min_Y,$max_Y) {
        $this->__range = array($min_X,$max_X,$min_Y,$max_Y);
        $this->__max_pairs = ($max_X - $min_X) * ($max_Y - $min_Y);
        $this->__history = array();
    }
}

// test

$c = new c(0,10,0,20);

$i = 0;
$pairs = array();
while ($i < 100) {
    $i++;
    $pair = $c->getRandUniquePair();

    if (in_array($pair,$pairs)) {
        die('Duplicate pairs!');
    }

    echo $pair[0].', '.$pair[1]."\n";
    $pairs[] = $pair;
}

$c->setRange(0,100000000000,0,100000000000);
echo "I perform well even at large ranges!\n";

$i = 0;
while ($i < 1000) {
    $i++;
    $pair = $c->getRandUniquePair();

    echo $pair[0].', '.$pair[1]."\n";
}

?>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-02
    • 2021-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多