阵列的独特组合

时间:2013-07-25 14:21:53

标签: php arrays unique combinations

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

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)第二个是写一个从这些范围产生一对的函数,然后将它存储在一个变量中,每次该函数在产生一对后调用,它会检查这对在递归调用函数之前是否产生,它会一直持续到它产生一对独特的。 这段代码:

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

我想要更好的算法。

1 个答案:

答案 0 :(得分: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";
}

?>