多个排序数组的交集

zan*_*ngw 0 c++ arrays sorting algorithm

这个,我们知道要解决两个排序的数组的交叉方法。那么如何得到多个排序数组的交集呢?

根据两个已排序数组的答案,我们可以将其应用于多个数组。这里是代码

vector<int> intersectionVector(vector<vector<int> > vectors){
    int vec_num = vectors.size();

    vector<int> vec_pos(vec_num);// hold the current position for every vector
    vector<int> inter_vec; // collection of intersection elements

    while (true){
        int max_val = INT_MIN;
        for (int index = 0; index < vec_num; ++index){
            // reach the end of one array, return the intersection collection
            if (vec_pos[index] == vectors[index].size()){
                return inter_vec;
            }

            max_val = max(max_val, vectors[index].at(vec_pos[index]));
        }

        bool bsame = true;
        for (int index = 0; index < vec_num; ++index){
            while (vectors[index].at(vec_pos[index]) < max_val){
                vec_pos[index]++; // advance the position of vector, once less than max value
                bsame = false;
            }
        }

        // find same element in all vectors
        if (bsame){
            inter_vec.push_back(vectors[0].at(vec_pos[0]));

            // advance the position of all vectors
            for (int index = 0; index < vec_num; ++index){
                vec_pos[index]++;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来解决它?

更新1

从这两个主题12来看,这似乎Hash set是更有效的方法。

更新2

为了提高性能,也许min-heap可以vec_pos在我上面的代码中使用 代替。变量max_val保存所有向量的当前最大值。所以只需将根值与 比较max_val,如果它们相同,则可以将此元素放入交集列表。

Bau*_*gen 5

要获得两个排序范围的交集,std::set_intersection可以使用:

std::vector<int> intersection (const std::vector<std::vector<int>> &vecs) {

    auto last_intersection = vecs[0];
    std::vector<int> curr_intersection;

    for (std::size_t i = 1; i < vecs.size(); ++i) {
        std::set_intersection(last_intersection.begin(), last_intersection.end(),
            vecs[i].begin(), vecs[i].end(),
            std::back_inserter(curr_intersection));
        std::swap(last_intersection, curr_intersection);
        curr_intersection.clear();
    }
    return last_intersection;
}
Run Code Online (Sandbox Code Playgroud)

这看起来比您的解决方案更清晰,因为您的解决方案太混乱而无法检查正确性。它还具有最佳复杂度。

标准库算法set_intersection可以以任何使用

至多 2·(N1+N2-1) 次比较,其中 N1 = std::distance(first1, last1) 和 N2 = std::distance(first2, last2)。

first1等是定义输入范围的迭代器。如果它是开源的(如 libstd++ 或 libc++),您可以在标准库的源代码中查看实际实现。