我又来套方案了,有个php数组数据处理问题,请问大家有没有好的方案

例子如下

$groups = [
    'a' => [1, 2, 3, 4],
    'b' => [2, 3],
    'c' => [2, 5, 6, 7]'d' => [7,9,10],
];
结果
$group = [
    'a' =>  [1,4],
    'c' => [5,6],
    'd' => [9,10],
    'a_more' => [2,3],
    'c_more' =>[7],
];

例子举的少,实际上会出现二十个左右分组,每组数据数量几十到一两万左右,要将当前key下的数组分成在其他组出现过和只在当前组出现过的两组数据,且出现过的同时在其他组也会被unset掉,不会出现重复数据,怎么处理开销会小一些

最佳答案

想到一个时间复杂度 f(n), 空间复杂度 f(n) 的算法

用一个数组记录首次出现的位置,处理后将其标记为 true, 详细看代码

$groups = [
    'a' => [1, 2, 3, 4],
    'b' => [2, 3],
    'c' => [2, 5, 6, 7],
    'd' => [7,9,10],
];

$has = [];
foreach ($groups as $key => $group) {
    if (str_ends_with($key, '_more')) {
        continue;
    }
    foreach ($group as $key2 => $val) {
        if (isset($has[$val])) {
            unset($groups[$key][$key2]);
            if (is_array($has[$val])) { // 第一次记录位置
                unset($groups[$has[$val][0]][$has[$val][1]]);
                $has[$val] = true;
            }

            if (isset($groups[$key.'_more'])) {
                $groups[$key . '_more'][] = $val;
            } else {
                $groups[$key.'_more'] = [$val];
            }

            if (empty($groups[$key])) {
                unset($groups[$key]);
            }
        } else { // 未出现记录位置
            $has[$val] = [$key, $key2];
        }
    }
}
dump($groups);
2个月前 评论
伽蓝幻梦 (楼主) 1个月前
kis龍 (作者) 1个月前
讨论数量: 13

感觉循环再array_intersect(),array_diff()的不太好,双层循环

2个月前 评论

遍历所有的元素两次,第一次计数,第二次根据总数与当前次数决定是否保留

2个月前 评论
伽蓝幻梦 (楼主) 2个月前
JinBB (作者) 2个月前
bneglect 2个月前

基于下面这几个变量,应该就比较好实现了

    $groups = [
        'a' => [1, 2, 3, 4],
        'b' => [2, 3],
        'c' => [2, 5, 6, 7],
        'd' => [7, 9, 10],
    ];

    //全部元素
    $all_value_arr = [];
    foreach ($groups as $k => $item) {
        $all_value_arr = array_merge($item, $all_value_arr);
    }
    //全部不重复元素
    $all_diff_value_arr  =array_unique($all_value_arr);

    //全部元素出现次数
    $all_value_count_arr = array_count_values($all_value_arr);

    print_r($all_value_arr);
    print_r($all_diff_value_arr);
    print_r($all_value_count_arr);die;
2个月前 评论
伽蓝幻梦 (楼主) 2个月前

变量用完就释放,另外处理的时候尽量用原生方法处理,基本也就这两个原则

2个月前 评论

想到一个时间复杂度 f(n), 空间复杂度 f(n) 的算法

用一个数组记录首次出现的位置,处理后将其标记为 true, 详细看代码

$groups = [
    'a' => [1, 2, 3, 4],
    'b' => [2, 3],
    'c' => [2, 5, 6, 7],
    'd' => [7,9,10],
];

$has = [];
foreach ($groups as $key => $group) {
    if (str_ends_with($key, '_more')) {
        continue;
    }
    foreach ($group as $key2 => $val) {
        if (isset($has[$val])) {
            unset($groups[$key][$key2]);
            if (is_array($has[$val])) { // 第一次记录位置
                unset($groups[$has[$val][0]][$has[$val][1]]);
                $has[$val] = true;
            }

            if (isset($groups[$key.'_more'])) {
                $groups[$key . '_more'][] = $val;
            } else {
                $groups[$key.'_more'] = [$val];
            }

            if (empty($groups[$key])) {
                unset($groups[$key]);
            }
        } else { // 未出现记录位置
            $has[$val] = [$key, $key2];
        }
    }
}
dump($groups);
2个月前 评论
伽蓝幻梦 (楼主) 1个月前
kis龍 (作者) 1个月前

千万级别用roraingbitmap , 十几万级别直接遍历就行

1个月前 评论
伽蓝幻梦 (楼主) 1个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!