简体   繁体   English

比较两个 std::vectors/arrays 或通常两个 stl contianers

[英]Comparing two std::vectors/arrays or in general two stl contianers

I have two arrays/vectors of strings for example例如,我有两个字符串数组/向量

str1_arr = ["hello","my","dear","world"]
str2_arr = ["dear","my","world","hello"]

the position/sequence of the words aren't the same.单词的位置/顺序不一样。 I would like to know if each element in str1_arr is present in str2_arr not really caring its position inside the container.我想知道 str1_arr 中的每个元素是否存在于 str2_arr 中,而不是真正关心容器内的 position。

Came across few discussion here and here but the answers are way back in 2011. Given that c++ has progressed some much, wondering if there is a better way of doing it using std::algorithms这里这里很少讨论,但答案可以追溯到 2011 年。鉴于 c++ 已经取得了很大进展,想知道是否有更好的方法来使用 std::algorithms

Thanks谢谢

Update更新

Well here is a non modifying and a modifying version.那么这里是一个非修改和修改版本。 Al tough sorting and copying seems like a lot of work, the highest complexity, which is of sorting is log(n) * n, and includes is just 4 * n, plus some linear ns, which is a lot less than n^2.艰难的排序和复制似乎需要很多工作,排序的最高复杂度是log(n) * n,包含只有4 * n,加上一些线性ns,比n^2小很多. (Approximating the size/distance of both ranges with n, which is simply the size of the bigger one) (用 n 近似两个范围的大小/距离,这只是较大的范围的大小)

So for the big O notation, this solution is in O(n *log(n)) instead of O(n^2) of the naive for of for solution or std::is_permutation (which is also wrong in the results).所以对于大 O 表示法,这个解决方案是 O(n *log(n)) 而不是 O(n^2) 的天真 for of 解决方案或std::is_permutation (这在结果中也是错误的)。

But I wondered, it still a pretty high constant factor of the complexity so I calculated:但我想知道,它仍然是复杂性的一个相当高的常数因素,所以我计算了:

Even the worst case, which would have 2 n from copying, 2(log(n) * n) from sorting and the 2(2n) from includes, is less than the n^2, of a naive solution, for a container only of the size of 14 elements .即使是最坏的情况,即复制有 2 n、排序有 2(log(n) * n) 和包含有 2(2n),也小于 n^2 的幼稚解决方案,仅适用于容器14 个元素的大小。

#include <iostream>
#include <vector>
#include <array>
#include <string>
#include <algorithm>
#include <iterator>


template<typename Iterator1, typename Iterator2>
bool is_included_general_modifying(Iterator1 begin1, Iterator1 end1, Iterator2 begin2, Iterator2 end2) {
    std::sort(begin1, end1);
    std::sort(begin2, end2);
    return std::includes(begin2, end2, begin1, end1);
}

template<typename Iterator1, typename Iterator2>
bool is_included_general(Iterator1 begin1, Iterator1 end1, Iterator2 begin2, Iterator2 end2) {
    const auto first_range_is_sorted = std::is_sorted(begin1, end1);
    const auto second_range_is_sorted = std::is_sorted(begin2, end2);
    if (first_range_is_sorted && second_range_is_sorted) {
        return std::includes(begin2, end2, begin1, end1);
    } else if (first_range_is_sorted) {
        auto second_range_copy = std::vector<typename std::iterator_traits<Iterator2>::value_type>(begin2, end2);
        auto new_begin2 = second_range_copy.begin(), new_end2 = second_range_copy.end();
        std::sort(new_begin2, new_end2);
        return std::includes(new_begin2, new_end2, begin1, end1);
    } else if (second_range_is_sorted) {
        auto first_range_copy = std::vector<typename std::iterator_traits<Iterator1>::value_type>(begin1, end1);
        auto new_begin1 = first_range_copy.begin(), new_end1 = first_range_copy.end();
        std::sort(new_begin1, new_end1);
        return std::includes(begin2, end2, new_begin1, new_end1);
    }
    auto first_range_copy = std::vector<typename std::iterator_traits<Iterator1>::value_type>(begin1, end1);
    auto new_begin1 = first_range_copy.begin(), new_end1 = first_range_copy.end();
    std::sort(new_begin1, new_end1);
    auto second_range_copy = std::vector<typename std::iterator_traits<Iterator2>::value_type>(begin2, end2);
    auto new_begin2 = second_range_copy.begin(), new_end2 = second_range_copy.end();
    std::sort(new_begin2, new_end2);

    return std::includes(new_begin2, new_end2, new_begin1, new_end1);
}

int main() {
    std::array<std::string, 4> str1_arr = {"hello", "my", "dear", "world"};
    std::vector<std::string> str2_arr = {"additional element", "dear", "my", "world", "hello"};
    std::cout << is_included_general(str1_arr.begin(), str1_arr.end(), str2_arr.begin(), str2_arr.end()) << "\n";
}
std::vector<std::string> str1_arr{"hello", "my", "dear", "world"};
std::vector<std::string> str2_arr{"dear", "my", "world", "hello"};

assert(std::is_permutation(str1_arr.begin(), str1_arr.end(), 
                           str2_arr.begin(), str2_arr.end()));

According to C++ reference , std::is_permutation(first1, last1, first2, last2) returns true if there exists a permutation of the elements in the range [first1, last1) that makes that range equal to the range [first2, last2) .根据C++ 参考,如果范围[first1, last1)中的元素存在排列使该范围等于范围[first2, last2) last2) ,则std::is_permutation(first1, last1, first2, last2)返回true

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM