【问题标题】:Find all intersections between 3 PHP arrays查找 3 个 PHP 数组之间的所有交集
【发布时间】:2012-12-21 23:35:04
【问题描述】:

我不知道如何在 3 个 PHP 数组中找到所有“对”和“三元组”。我的数组如下所示:

Array
(
    [0] => Array
        (
            [sanitized] => lisa
            [original] => Lisa
            [weight] => 100
            [color] => blank
        )

    [1] => Array
        (
            [sanitized] => jack
            [original] => Jack
            [weight] => 93
            [color] => blank
        )
    ...

这些数组有 3 个;它们始终按整数键排序,并且始终包含 10 个索引 (0-9)。我想做的是:

  • 在 2 个数组或所有 3 个数组中查找相同名称的实例(通过比较“已清理”字段),并将它们的“颜色”更改为相同(即我不想只查找交集在所有 3 个数组之间 - 可以使用 array_intersect 完成)
  • 构建第 4 个数组,该数组连接所有条目,并通过将它们的权重相加(颜色无关紧要)来组合相同的名称(通过比较“净化”字段)
  • 由于这些任务相似,我想同时完成它们,并尽量减少复杂性

这很难解释,所以我用视觉表示。

颜色:

Colors http://www.tsiomenko.com/1.png

重量:

Weights http://www.tsiomenko.com/2.png

我有一些工作代码,但它确实很长、很丑陋,并且具有类似 N^3 的复杂性 - 我使用嵌套的 for 循环多次遍历所有数组,直到我得到我需要的东西。尽管我正在使用非常小的数组,但我想知道如何有效地做到这一点,因为我很好奇其他人将如何解决这个问题。欢迎使用伪代码而不是 PHP 来解决这个问题。

【问题讨论】:

  • 如何确定条目的主色,例如当 Lisa 在数组 1 中具有“绿色”而在数组 2 中具有“黄色”时,您怎么知道要设置哪种颜色。将选择哪种颜色?此外,在示例中,颜色为“空白”。您从哪里获得要分配的颜色?
  • @Gordon 我认为这并不重要(实际上只是f(name)) - 在输出中有同一个人的同色高光(在 3 中出现 2/3 次)输入)。
  • @Gordon - 选择的颜色无关紧要,只要每组相同的名称都有自己的颜色。现在我只是从预制数组中提取随机颜色,然后确保不会再次选择该颜色。还应该提到每个数组都是一个集合(即单个数组中的所有名称都是唯一的)。
  • 你的标题说你想找到所有的交叉点,但你的要求是加入所有的数组?你能澄清一下你是想加入所有值还是只加入相交的值?
  • @Gordon - 抱歉,如果使用不正确的集合术语令人困惑。我正在尝试 1)用单独的颜色标记所有相同值的组,以及 2)创建第 4 个集合,该集合连接所有值并对相同值的权重求和。这有点像一个两部分的问题。很难解释,我试着画了一张。

标签: php data-structures set asymptotic-complexity


【解决方案1】:

下面的循环应该给出你需要的输出:

// loop once to build the combined array and set the colors
foreach ($names as &$name) {
    if (!isset($combined[$name['sanitized']])) {
        $combined[$name['sanitized']] = array(
            'original' => $name['original'],
            'weight'   => $name['weight'],
            'color'    => array_pop($colors),
            'count'    => 1,
        );
    } elseif ($combined[$name['sanitized']]['count'] < 3) {
        $combined[$name['sanitized']]['weight'] += $name['weight'];
        $combined[$name['sanitized']]['count']++;
    }

    $name['color'] = $combined[$name['sanitized']]['color'];
}


// loop again to blank any colors where name only appeared once
foreach ($names as &$name) {
    if ($combined[$name['sanitized']]['count'] === 1) {
        $combined[$name['sanitized']]['color'] = $name['color'] = 'blank';
    }
}

我省略了颜色生成器,那里有很多 SO 问题。如果找到超过 3 个匹配项,那么这里仍然有些不清楚该怎么办,因此您可能必须修改上述内容以满足您的需要。

Here's a Gisthere's the generated output

【讨论】:

  • 正是我要找的 - 请注意,有 3 个单独的“名称”数组,但我想通了。感谢您非常彻底的回复!
猜你喜欢
  • 1970-01-01
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多