Php 阵列的唯一组合

Php 阵列的唯一组合,php,arrays,unique,combinations,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; }

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

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;
}

}
但这有一个问题,有时抛出
致命错误:达到最大函数嵌套级别“100”


我想要更好的算法

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

是获取指定范围内随机整数的一种很好的方法,而无需像上面的示例中那样构造或操作值数组

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

<?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";
}

?>

当我尝试这段代码时,我得到了以下错误:致命错误:在test.php的第35行调用未定义的方法a::b()。b(数组…做什么?