【问题标题】:Merge partially similar arrays合并部分相似的数组
【发布时间】:2020-06-07 16:19:48
【问题描述】:

我在数组中有值,它们部分包含相同的值,但每个数组仅包含值的一些随机子集,例如:

$array1 = array("value2", "value3", "value5", "value6");
$array2 = array("value1", "value2", "value3", "value4", "value5");
$array3 = array("value1", "value3", "value4", "value5", "value6" , "value7");

我需要通过以下方式合并这种数组(当然也可以多于3个):

  1. 应该有一个输出数组,其中包含输入数组中出现的所有值保持原始顺序。 (值之间没有其他逻辑关系(如字母顺序等),它们的位置由它们在输入数组中的分布定义。但至少在后台,每个值都有一个绝对位置,所以这是不可能的在一个输入数组中获取 ...value1, value2...,在另一个输入数组中获取 ...value2, value1...。同样重要的是,值在数组中始终是唯一的,它们不能重复出现。 ) 对于给定的输入,输出应该是:

    $输出:数组 ( [0] => "值1" [1] =>“价值2” [2] => “价值 3” [3] => “价值 4” [4] =>“价值5” [5] =>“价值6” [6] =>“价值7” )

  2. 我需要展示,它是如何被发现和合并的,就像一个完整的外部连接,但要保持顺序。输出应如下所示:

我正在考虑使用 array_merge,或者将它与 array_diff 结合使用,但我不确定如何将它们一起使用。我的想法是从最短的输入数组开始,然后通过获取较长的数组来构建合并集。

提前谢谢你。

【问题讨论】:

    标签: php arrays


    【解决方案1】:

    您可以使用此类合并任意数量的数组

    <?php
    
      class mergeArrays {
          private $_arrays ;// keeps an array of arrays that we're going to merge 
          private $arrays_length ;// keeps the length of each array
    
          function __construct() {
              $this->_arrays = [] ;
              $this->arrays_length = [] ;
          }
    
          function add_array($arr) {
              sort($arr);
              $this->_arrays[] = $arr ;
              $this->arrays_length[] = count($arr);
          }
    
          protected function _comp($val1 , $val2) {
              return strcmp($val1,$val2);
          }
    
          function merge() {
              $res = [];
              $indexes = array_fill(0, count($this->_arrays), 0);
              $exit = false;
              while(!$exit) {
                  $min_val = '';
                  $min_index = -1;
                  for($i =0 ; $i < count($this->_arrays); $i++) { 
                    if($indexes[$i] != -1 && $indexes[$i] >= $this->arrays_length[$i]) {
                        $indexes[$i] = -1 ; // it means we check all members of `$i`th array
                    }
                    if($indexes[$i] != -1 ) {
                        if($min_index === -1 ){
                            $min_index = $i;
                            $min_val = $this->_arrays[$i][$indexes[$i]]; 
                        } else {
                            $cmp_res = $this->_comp( $this->_arrays[$i][$indexes[$i]] ,$min_val );
                            if($cmp_res == -1 ){
                                $min_index = $i;
                                $min_val = $this->_arrays[$i][$indexes[$i]]; 
                            } else if($cmp_res === 0 ) {
                                $indexes[$i]++;
                            }
                        }
                      }
                  }
    
                  if($min_index > -1 ) {
                      if(count($res) ===0 || $res[count($res)-1] != $min_val ){
                          $res[] = $min_val;
                      }
                      $indexes[$min_index]++;
                  } else {
                      $exit = true ;
                  }
              }
              return $res;
          }
      }
    
      $array1 = array("value2", "value3", "value5", "value6");
      $array2 = array("value1", "value2", "value3", "value4", "value5");
      $array3 = array("value1", "value3", "value4", "value5", "value6" , "value7");
    
      $obj = new mergeArrays();
      $obj->add_array($array1);
      $obj->add_array($array2);
      $obj->add_array($array3);
    
      var_dump($obj->merge());
    

    【讨论】:

    • 你确定吗?如果我运行它,我会得到以下结果: array(11) { [0]=> string(6) "value2" [1]=> string(6) "value3" [2]=> string(6) " value5" [3]=> string(6) "value6" [4]=> string(6) "value1" [5]=> string(6) "value2" [6]=> string(6) "value3" [7]=>字符串(6)“value4”[8]=>字符串(6)“value5”[9]=>字符串(6)“value6”[10]=>字符串(6)“value7”}
    • 我在第 39 行犯了一个错误,我修复了它。我还在第 50 行添加了一个额外条件,以防输入数组有重复的元素
    • 太好了,现在它工作正常,但是在输出中,值是按升序排列的,而不是按照它们最初在输入中相互跟随的顺序。例如,如果我镜像输入数组,输出仍然包含 value1...7,而不是相反。我会看看你的代码细节顺便说一句,我真的很想了解你是如何实现的。
    • 一种更简单的方法是在结果数组中添加输入数组的每一项,但在添加项之前,您应该检查结果数组中不存在所选项
    猜你喜欢
    • 2020-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 2014-10-14
    • 2018-11-04
    相关资源
    最近更新 更多