给定两个排序的向量,包括介于0和一些已知的&n;之间的唯一值。并且一个向量(set1)的大小总是大于候选向量set2的大小。
查询:是否确定给定的set2是否是set1的子集?
除了C ++ 11中的以下实现之外,它们是否有更好,更有效的方法?
#include <iostream>
#include <vector>
bool subSetCheck(std::vector<int> set1, std::vector<int> set2) {
//Set1 & 2 are always sorted and contain only unique integers from 0 to some known 'n'
//Set1 is always larger than Set2 in size
std::vector<int>::iterator it1 = set1.begin();
std::vector<int>::iterator it2 = set2.begin();
bool subSet = true;
for (; (it1 != set1.end()) && (it2 !=set2.end()) ;) {
if ( *it1 == *it2) {++it1; ++it2;}
else if( *it1 > *it2) ++it2;
else ++it1;
}
if (it1 ==set1.end()) subSet = false;
return subSet;
}
int main () {
std::vector<int> set1{0,1,2,3,4};
std::vector<int> set2{0,1,5};
if (subSetCheck(set1,set2)) std::cout << "Yes, set2 is subset of set1." << std::endl;
else std::cout << "No! set2 is not a subset of set1." << std::endl;
return 0;
}
答案 0 :(得分:5)
您可以使用std::includes
:
std::vector<int> a{1,2,3,4,5};
std::vector<int> b{1,2,6};
std::cout << std::includes(a.begin(), a.end(), b.begin(), b.end()) << std::endl;
答案 1 :(得分:0)
是的,有更有效的方法。你的问题的答案取决于你是否在大多数情况下假设,矢量将是一个子集,或者不是。
这都是假设没有重复的元素。
让我们这样看待它。如果vec2恰好是vec1的一个子集,那么验证将采用O(vec1.size()),因为你必须查看每个元素。
在这种情况下,您的实施已经非常接近最优。您可以通过使用二进制搜索来查找vec1中的第一个匹配元素,而不是像现在一样进行线性搜索。
一旦你找到了这个元素,你就无法做其他事情而不是遍历所有元素并进行比较。
另一方面,如果你假设set2的大部分时间而不是是set1的嫌疑人,你应该采用不同的方法。
开头是一样的:使用二进制搜索在set1中找到set2的第一个元素。
然后,使用二进制搜索在set1中查找set2的最后一个元素。
然后,检查范围的大小是否与set2的大小匹配。如果没有,你现在可以拯救。
最后,如果大小匹配,请逐个元素进行比较。
如果你有重复的元素,事情变得棘手,并且弄清楚如何做到这一点留给读者做练习。