更新
这里有一个非修改版本和一个修改版本。艰难的排序和复制似乎需要很多工作,排序的最高复杂度是 log(n) * n,包含只有 4 * n,加上一些线性 ns,比 n^2 小很多. (用 n 近似两个范围的大小/距离,这只是较大的范围的大小)
所以对于大 O 表示法,这个解决方案是 O(n *log(n)) 而不是 O(n^2) 的天真 for 解决方案或 std::is_permutation (结果也是错误的)。
但我想知道,它仍然是复杂性的一个相当高的常数因素,所以我计算了:
即使是最坏的情况,即复制中的 2 n、排序中的 2(log(n) * n) 和包含中的 2(2n),也小于简单解决方案的 n^2,例如只有14 elements 大小的容器。
#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";
}