Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 使用组在复杂的数字范围内迭代(循环)生成括号表_Php_Loops_Iteration - Fatal编程技术网

Php 使用组在复杂的数字范围内迭代(循环)生成括号表

Php 使用组在复杂的数字范围内迭代(循环)生成括号表,php,loops,iteration,Php,Loops,Iteration,我试图建立一个算法来处理比赛的括号表。我需要看一系列的数字。每个号码都会有运动员的名字。号码是随机分配给运动员的,但号码的配对必须始终保持不变。有两组奇数和偶数,即A和B 唯一的问题是,我找不到正确的算法来精确地迭代数字,如下所示: Group A: -------- 1 17 9 25 ------ 5 21 13 29 ------ 3 19 11 27 ------ 7 23

我试图建立一个算法来处理比赛的括号表。我需要看一系列的数字。每个号码都会有运动员的名字。号码是随机分配给运动员的,但号码的配对必须始终保持不变。有两组奇数和偶数,即A和B

唯一的问题是,我找不到正确的算法来精确地迭代数字,如下所示:

Group A:
--------
  1
  17

  9
  25
------
  5
  21

  13
  29
------
  3
  19

  11
  27
------                         
  7
  23

  15
  31


Group B:
--------
  2
  18

  10
  26
------                          
  6
  22

  14
  30
------   
  4
  20

  12
  28
------
  8
  24

  16
  32
有没有人能提供一些建议或例子来说明如何获得上面的输出

编辑1: 上面的例子是32名运动员的支架板!如果您为4、8、16、64或128名运动员使用工作表,则必须应用相同的逻辑

编辑2: 让我们以4名运动员的床单和16名运动员的床单为例来说明这一点

4名运动员的名单:

Group A:
--------
  1
  3

Group B:
--------
  2
  4
Group A:
--------
  1
  9

  5
  13
------
  3
  11

  7
  15

Group B:
--------
  2
  10

  6
  14
------                              
  4
  12

  8
  16
$participants = array(
array("John", 0),
array("Gagan", 0),
array("Mike Tyson", 1),
array("Gair", 0),
array("Gale", 0),
array("Roy Johnes", 1),
array("Galip", 0),
array("Gallagher", 0),
array("Garett", 0),
array("Nikolai Valuev", 1),
array("Garner", 0),
array("Gary", 0),
array("Gelar", 0),
array("Gershom", 0),
array("Gilby", 0),
array("Gilford", 0)
);
16名运动员的名单:

Group A:
--------
  1
  3

Group B:
--------
  2
  4
Group A:
--------
  1
  9

  5
  13
------
  3
  11

  7
  15

Group B:
--------
  2
  10

  6
  14
------                              
  4
  12

  8
  16
$participants = array(
array("John", 0),
array("Gagan", 0),
array("Mike Tyson", 1),
array("Gair", 0),
array("Gale", 0),
array("Roy Johnes", 1),
array("Galip", 0),
array("Gallagher", 0),
array("Garett", 0),
array("Nikolai Valuev", 1),
array("Garner", 0),
array("Gary", 0),
array("Gelar", 0),
array("Gershom", 0),
array("Gilby", 0),
array("Gilford", 0)
);
编辑3: 最后一部分,我计划创建一个包含运动员姓名及其状态的数组。 所谓状态,我的意思是,如果运动员以前是冠军(强者),那么他/她获得1作为状态,如果运动员以前的成绩不为人所知或最低(弱者),那么状态为0。这样,我们就可以将实力最强的运动员分成不同的小组,确保他们不会在第一场比赛中相互对抗,而是在接近半决赛或决赛时相遇

PHP数组示例:

Group A:
--------
  1
  3

Group B:
--------
  2
  4
Group A:
--------
  1
  9

  5
  13
------
  3
  11

  7
  15

Group B:
--------
  2
  10

  6
  14
------                              
  4
  12

  8
  16
$participants = array(
array("John", 0),
array("Gagan", 0),
array("Mike Tyson", 1),
array("Gair", 0),
array("Gale", 0),
array("Roy Johnes", 1),
array("Galip", 0),
array("Gallagher", 0),
array("Garett", 0),
array("Nikolai Valuev", 1),
array("Garner", 0),
array("Gary", 0),
array("Gelar", 0),
array("Gershom", 0),
array("Gilby", 0),
array("Gilford", 0)
);
从这个例子中我们可以看到,那些状态为1的人必须在不同的组中,即A和B。但是我们只有两组数字奇数和偶数,在这个例子中,有3名强壮的运动员。因此,其中两人将在同一组。最后的结果必须是,这两名来自同一组的强手在第一场比赛中不能相遇(这意味着他们不会在同一对号码上,并且尽可能远离对方,所以他们也不会在第二场比赛中相遇)


然后随机地,我计划重新安排阵型,每次都把运动员送到括号中-,每次都有不同的数字,,那些有国旗1的运动员去不同的小组,并且/或者每次都在第一场比赛中不见面,运动员的姓名分配给同一对号码。

此粗略代码可能就是您想要的:

<?php

class Pair
{
    public $a;
    public $b;

    function __construct($a, $b) {
        if(($a & 1) != ($b & 1)) 
            throw new Exception('Invalid Pair');
        $this->a = $a;
        $this->b = $b;
    }
}

class Competition
{
    public $odd_group = array();
    public $even_group = array();

    function __construct($order) {
        $n = 1 << $order;
        $odd = array();
        $even = array();
        for($i = 0; $i < $n; $i += 4) {
            $odd[] = $i + 1;
            $odd[] = $i + 3;
            $even[] = $i + 2;
            $even[] = $i + 4;
        }
        shuffle($odd);
        shuffle($even);
        for($i = 0; $i < count($odd); $i += 2) {
            $this->odd_group[] = new Pair($odd[$i], $odd[$i+1]);
            $this->even_group[] = new Pair($even[$i], $even[$i+1]);
        }
        echo "Odd\n";
        for($i = 0; $i < count($this->odd_group); ++$i) {
            $pair = $this->odd_group[$i]; 
            echo "{$pair->a} vs. {$pair->b}\n";
        }
        echo "Even\n";
        for($i = 0; $i < count($this->even_group); ++$i) {
            $pair = $this->even_group[$i]; 
            echo "{$pair->a} vs. {$pair->b}\n";
        }
    }
}

new Competition(5);

?>

考虑到参与者的数量始终是2的幂,这段代码应该给出您期望的顺序

function getOrder($numberOfParticipants) {
    $order = array(1, 2);

    for($i = 2; $i < $numberOfParticipants; $i <<= 1) {
        $nextOrder = array();
        foreach($order as $number) {
            $nextOrder[] = $number;
            $nextOrder[] = $number + $i;
        }
        $order = $nextOrder;
    }

    return $order; // which is for instance [1, 17, 9, 25, and so on...] with 32 as argument
}
我使用的算法与逻辑完全相同。我从一个只包含
[1,2]
的数组开始,
$I
实际上是这个数组的大小。然后我计算下一行,直到我到达一个有适当数量参与者的行

Participants | Order
           2 | 1   2
           4 | 1   3=1+2   2   4=2+2
           8 | 1   5=1+4   3   7=3+4   2   6=2+4   4   8=4+4
         ... |
           N | 1         X         Y         Z         ...
          2N | 1   1+N   X   X+N   Y   Y+N   Z   Z+N   ...

附带说明:
$i好的,我终于成功地将我的Tcl代码转换成PHP!我也改变了一些事情:

<?php

// Function generating order participants will be placed in array
function getBracket($L) {
    // List will hold insert sequence
    $list = array();
    // Bracket will hold final order of participants
    $bracket = array();
    // The algorithm to generate the insert sequence
    for ($n = 1; $n <= $L; $n += 1) {
        // If 'perfect' number, just put it (Perfect no.s: 2, 4, 8, 16, 32, etc)
        if (substr(log($n)/log(2), -2) == ".0") {
            $list[] = $n;
        // If odd number, stuff...
        } elseif ($n % 2 == 1) {
            $list[] = $list[($n-1)/2];
        // Else even number, stuff...
        } else {
            $list[] = $list[$n/2-1]+$n/2;
        }
    }

    // Insert participant order as per insert sequence
    for ($i = 1; $i <= sizeof($list); $i += 1) {
        $id = $i-1;
        array_splice($bracket, $list[$id], 0, $i);
    }
    return $bracket;
}

// Find number of participants over 'perfect' number if any
function cleanList($L) {
    for ($d = 1; $L > $d; $d += 1) {
        $sq = $L-pow(2,$d);
        if($sq == 0) {break;}
        if($sq < 0) {
            $d = pow(2,$d-1);
            $diff = $L-$d;
            break;
        }
    }
    return $diff;
}

$participants = array(
    array(0, "John", 2),
    array(1, "Gagan", 1),
    array(2, "Mike Tyson", 1),
    array(3, "Gair", 1),
    array(4, "Gale", 0),
    array(5, "Roy Johnes", 0),
    array(6, "Galip", 0),
    array(7, "Gallagher", 0),
    array(8, "Garett", 0),
    array(9, "Nikolai Valuev", 0),
    array(10, "Garner", 1),
    array(11, "Gary", 0),
    array(12, "Gelar", 0),
    array(13, "Gershom", 1),
    array(14, "Gilby", 0),
    array(15, "Gilford", 1),
    array(16, "Arianna", 0)
);

// Extract strength of participant
foreach ($participants as $array) {
    $finorder[] = $array[2];
}
// Sort by strength, strongest first
array_multisort($finorder,SORT_DESC,$participants);

$order = array();
$outside = array();

// Remove participants above 'perfect' number
$remove = cleanList(sizeof($participants));
for ($r = 1; $r <= $remove; $r += 1) {
    $removed = array_shift($participants);
    $outside[] = $removed;
}

// Get corresponding bracket
$res = getBracket(sizeof($participants));
foreach ($res as $n) {
    $order[] = $n;
}

// Align bracket results with participant list
array_multisort($order, $participants);
$participants = array_combine($res, $participants);

echo "The final arrangement of participants\n";
print_r($participants);
print_r($outside);
?>

为了获得元素插入顺序的逻辑,我使用了

另外,由于我对PHP不太熟悉,可能有一些方法可以缩短一些内容,但只要它能工作就行^^

编辑:修复了第一个参与者排序和添加新票号的问题。有关没有旧票证号码的结果,请参阅

EDIT2:管理将键移动到数组中;看

EDIT3:我认为“额外”参与者应该超出范围。如果希望括号中的值为null,则可以使用此值

EDIT4:不知怎的,代码板上的PHP版本破坏了一些东西。。。在下面修复它并删除初始索引…:

<?php

    // Function generating order participants will be placed in array
    function getBracket($L) {
        // List will hold insert sequence
        $list = array();
        // Bracket will hold final order of participants
        $bracket = array();
        // The algorithm to generate the insert sequence
        for ($n = 1; $n <= $L; $n += 1) {
            // If 'perfect' number, just put it (Perfect no.s: 2, 4, 8, 16, 32, etc)
            if (int(log($n)/log(2)) || $n == 1) {
                $list[] = $n;
            // If odd number, stuff...
            } elseif ($n % 2 == 1) {
                $list[] = $list[($n-1)/2];
            // Else even number, stuff...
            } else {
                $list[] = $list[$n/2-1]+$n/2;
            }
        }

        // Insert participant order as per insert sequence
        for ($i = 1; $i <= sizeof($list); $i += 1) {
            $id = $list[$i-1]-1;
            array_splice($bracket, $id, 0, $i);
        }
        return $bracket;
    }

    // Find number of participants over 'perfect' number if any
    function cleanList($L) {
        for ($d = 1; $L > $d; $d += 1) {
            $diff = $L-pow(2,$d);
            if($diff == 0) {break;}
            if($diff < 0) {
                $diff = pow(2,$d)-$L;
                break;
            }
        }
        return $diff;
    }

    $participants = array(
        array("John", 2),
        array("Gagan", 1),
        array("Mike Tyson", 1),
        array("Gair", 1),
        array("Gale", 0),
        array("Roy Johnes", 0),
        array("Galip", 0),
        array("Gallagher", 0),
        array("Garett", 0),
        array("Nikolai Valuev", 0),
        array("Garner", 1),
    );

    // Extract strength of participant
    foreach ($participants as $array) {
        $finorder[] = $array[2];
    }
    // Sort by strength, strongest first
    array_multisort($finorder,SORT_DESC,$participants);

    $order = array();

    // Add participants until 'perfect' number
    $add = cleanList(sizeof($participants));
    for ($r = 1; $r <= $add; $r += 1) {
        $participants[] = null;
    }

    // Get corresponding bracket
    $res = getBracket(sizeof($participants));
    // Align bracket results with participant list
    foreach ($res as $n) {
        $order[] = $n;
    }
    array_multisort($order, $participants);
    $participants = array_combine($res, $participants);

    echo "The final arrangement of participants\n";
    print_r($participants);
?>



如何定义子组?子组I仅为4n+1,而子组II为4n+3?看起来你所有小组的成员资格都是以模4为基础的,这是否为你指明了正确的方向?这只是括号中表格的开始作业吗?迪特,谢谢你,这是一个很好的尝试,让奇数和偶数分开。唯一的问题是,配对号码必须始终保持相同。在你的例子中总是不同的。看:。您是否可以尝试使代码正常工作,并保持示例中所示的对数字。我将尝试更新我的答案与更多的细节@IliaRostovtsev我把它留给你。@IliaRostovtsev可能会对结果进行排序。usort()不会返回所需的
对数字,对吧!?你的代码工作方式真是太棒了。不过,我从来没有清楚地理解循环的
。如果您还可以对代码提供一些注释,这将对学习非常有用!您能否提供一个示例,说明如何根据问题中描述的状态标志与参与者数组协作?如果我正确理解您的期望,请添加一些解释和解决方案来处理您的状态。哎呀,计算组数时括号放错了。。。这一行现在是正确的
$neededGroups=1答案已更新,因此强壮的运动员可以更好地分布在团体和小组之间。作为奖励,
null
值现在也可以更好地传播(当需要时)。事实上,如果根本没有强大的运动员,这也是失败的。不管怎样,修正了!(在你的表意文字第63行的
if
附近)同样,代码的长度要短得多!不知道如何自动随机(洗牌)结果。作为作者,你能推荐一些东西吗?假设你有不同类别的比赛,但参赛者相同?然后他们将永远面对同样的对手(同样的一对)!?:)@这听起来像是另一个问题!如果配对没有限制,那么简单的方法听起来很理想。我知道
shuffle()
不能正常工作。但是是的!!!!终于解决了!!无论如何,谢谢你,我的朋友!!:你的代码很光荣@IliaRostovtsev呃我不知道你是怎么解决的