从数组生成一对的组合(abc - > ab:bc:ca或ac:ba:cb)

时间:2014-12-13 01:48:58

标签: php arrays combinations

我有一个像

这样的数组
print_r($emails);

显示器:

Array ( [0] => email1 [1] => email2 [2] => email3 [3] => email4 [4] => email5 )

我想创建$emails对的组合,输出示例:

  • email1有combi email4

  • email2有combi email1

  • email3有combi email5

  • email4有combi email2

  • email5有combi email3

所以,你不能拥有" email1具有combi email1",而且" email1具有combi email3,而email2具有combi email3"。

另请注意,此输出可以随时变化,$emails数组具有可变数量的项目(示例有5个,但可以是3个或更多)。

我现在试图为此创建一个代码数小时......在网上搜索。我真的希望有人可以帮助我。

2 个答案:

答案 0 :(得分:0)

在阅读了您的问题和您的评论中的澄清后,我会说您需要的是一个循环链表。如:

  email1 -> email2 -> email3 -> email1

只要有3封或者更多的电子邮件,就没有人会自己说话或者其他人收到的电子邮件。 email1和email3的位置以及所有这些无关紧要,所以它可以随机提及。

简单来说,当有3个人时:

  • Person1查看person2
  • Person2看人3
  • Person3查看person1

谁是person1,person2或person3永远不重要。如果比尔盖茨是3个人中的一个,那么他们中的哪一个并不重要。事实是,他永远不会看自己或其他人已被别人看过的人。这对我来说很简单。

我希望我没有过度简化它。

答案 1 :(得分:0)

如果我理解正确,每封电子邮件必须有一个“combi”(无论是什么),只有一封不同的电子邮件。

这相当于构建一个图形,其中每个节点只有一个传出(而不是自引用)顶点,这意味着它也有一个传入的顶点。

这意味着生成一个或所有图形,这些图形被划分为没有单例的循环。

例如,对于5个元素,您可以具有一个大的1-> 2-> 3-> 4-> 5个循环或两个1-> 2-> 3 / 4->。 5个周期

创建所有可能的组合对我来说看起来并不是一项微不足道的任务,虽然我不是图形专家,但我认为这个问题并不常见,已经被硬数学家研究过了。

我能提供的最佳近似值如下:

  1. 将您的“电子邮件”分区为包含至少2个元素的子集
  2. 在每个分区内创建周期
  3. 这种方法的问题是决定如何对初始集进行分区以获得同质结果。例如,在5个元素的情况下,您希望多久一次使用5个元素循环而不是3/2分区?

    我选择了一个简单的方法:首先在任何不会产生单件的位置切割初始组,然后其余部分经历相同的过程直到初始组耗尽。
    两个(非空)子集的递归分割可能会产生更均匀的结果,但由于我不太确定这个答案符合您的期望,我暂时将其留在那里。

    <?php
    $num_nodes = 6; // number of "e-mails"
    
    $nodes = range (1, $num_nodes); // these represent your e-mails
    $vertex = Array();              // these represent your "has as combi " relation
    
    shuffle($nodes); // random pick order
    
    // partition nodes into subsets of at least 2 elements
    $cycles = array();
    while (count($nodes) > 0)
    {
        $len = rand (1, count($nodes)-2);
        if ($len == 1) $len = 0; // take all remaining nodes
        $cycles[] = array_slice ($nodes, $len);
        array_splice ($nodes, $len);
    }
    
    // create cycles within each subset
    echo "Partitions:\n";
    foreach ($cycles as $cycle)
    {
        foreach ($cycle as $node) echo "$node->"; echo "\n";
        $len = count ($cycle);
        for ($i = 0 ; $i != $len ; $i++) $vertex[$cycle[$i]] = $cycle[($i+1)% $len];
    }
    
    // here you go...
    echo "\nRelations:\n";
    foreach ($vertex as $origin=>$destination) echo "$origin -> $destination\n";
    
    ?>
    

    示例输出:

    C:\Dev\PHP\_StackOverflow\PHP>php email_graph.php
    Partitions:
    3->5->1->
    4->6->2->
    
    Relations:
    3 -> 5
    5 -> 1
    1 -> 3
    4 -> 6
    6 -> 2
    2 -> 4
    
    C:\Dev\PHP\_StackOverflow\PHP>php email_graph.php
    Partitions:
    1->4->
    6->5->3->2->
    
    Relations:
    1 -> 4
    4 -> 1
    6 -> 5
    5 -> 3
    3 -> 2
    2 -> 6
    
    C:\Dev\PHP\_StackOverflow\PHP>php email_graph.php
    Partitions:
    3->4->6->5->1->2->
    
    Relations:
    3 -> 4
    4 -> 6
    6 -> 5
    5 -> 1
    1 -> 2
    2 -> 3