[英]Check whether two elements have a common element in C++
I want the function to return true when there is any element matching between two vectors, 我希望函数在两个向量之间存在任何元素匹配时返回true,
Note : My vectors are not sorted
Following is my source code, Note : My vectors are not sorted
以下是我的源代码,
bool CheckCommon( std::vector< long > &inVectorA, std::vector< long > &inVectorB )
{
std::vector< long > *lower, *higher;
size_t sizeL = 0, sizeH = 0;
if( inVectorA.size() > inVectorB.size() )
{
lower = &inVectorA;
sizeL = inVectorA.size();
higher = &inVectorB;
sizeH = inVectorB.size();
}
else
{
lower = &inVectorB;
sizeL = inVectorB.size();
higher = &inVectorA;
sizeH = inVectorA.size();
}
size_t indexL = 0, indexH = 0;
for( ; indexH < sizeH; indexH++ )
{
bool exists = std::binary_search( lower->begin(), lower->end(), higher->at(indexH) );
if( exists == true )
return true;
else
continue;
}
return false;
}
This is working fine when the size of vector B is less than the size of vector A , but returning false even there is match when size of vector B is greater than size of vector A . 当矢量B的大小小于矢量A的大小时,这工作正常,但是当矢量B的大小大于矢量A的大小时,即使存在匹配也返回假。
The problem with posted code is that you should not use std::binary_search
when the vector is not sorted. 发布代码的问题在于,当向量未排序时,不应使用std::binary_search
。 The behaviour is defined only for sorted range. 仅针对排序范围定义行为。
If the input vectors are not sorted then you can use find_first_of
to check for existence of first common element found. 如果输入向量未排序,则可以使用find_first_of
检查是否存在找到的第一个公共元素。
bool CheckCommon(std::vector<long> const& inVectorA, std::vector<long> const& nVectorB)
{
return std::find_first_of (inVectorA.begin(), inVectorA.end(),
nVectorB.begin(), nVectorB.end()) != inVectorA.end();
}
Complexity of find_first_of
is up to linear in inVectorA.size()*inVectorB.size()
; 的复杂性find_first_of
达到线性inVectorA.size()*inVectorB.size()
; it compares elements until a match is found. 它会比较元素直到找到匹配项。
If you want to fix your original algorithm then you can make a copy of one of vectors and std::sort
it, then std::binary_search
works with it. 如果你想修复原始算法,那么你可以复制一个向量和std::sort
它,然后std::binary_search
可以使用它。
In actual programs that do lot of such matching between containers the containers are usually kept sorted. 在容器之间进行大量此类匹配的实际程序中,容器通常保持分类。 Then the complexity of search is up to linear in inVectorA.size()+inVectorB.size()
. 然后, inVectorA.size()+inVectorB.size()
中搜索的复杂性达到线性。
std::find_first_of
is more efficient than to sort both ranges and then to search for match when both ranges are rather short or second range is shorter than binary logarithm of length of first range. std::find_first_of
比排序两个范围更有效,然后当两个范围相当短或第二个范围短于第一个范围长度的二进制对数时搜索匹配。
You can use a well-defined algorithm called as std::set_intersection
to check if there is any common element between these vectors. 您可以使用名为std::set_intersection
的定义良好的算法来检查这些向量之间是否存在任何公共元素。
Pre-condition :- Both vectors be sorted. 前提条件: - 两个向量都要排序。
Here is an implementation which uses sorted vectors, doesn't construct a new container, and which has only linear complexity (more detailed: O(container1.size()+ container2.size())
: 这是一个使用有序向量的实现,不构造一个新容器,并且只具有线性复杂度(更详细: O(container1.size()+ container2.size())
:
template< class ForwardIt1, class ForwardIt2 >
bool has_common_elements( ForwardIt1 first, ForwardIt1 last, ForwardIt2 s_first, ForwardIt2 s_last )
{
auto it=first;
auto s_it=s_first;
while(it<last && s_it<s_last)
{
if(*it==*s_it)
{
return true;
}
*it<*s_it ? ++it : ++s_it; //increase the smaller of both
}
return false;
}
You could do something like the following. 您可以执行以下操作。 Iterate over the first vector. 迭代第一个向量。 For each element, use std::find
to see if it exists in the other vector. 对于每个元素,使用std::find
查看它是否存在于另一个向量中。 If you find it, they have at least one common element so return true. 如果你找到它,它们至少有一个共同元素,所以返回true。 Otherwise, move to the next element of the first vector and repeat this process. 否则,移动到第一个向量的下一个元素并重复此过程。 If you make it all the way through the first vector without finding a common element, there is no intersection so return false. 如果你在没有找到公共元素的情况下完成第一个向量,那么就没有交集,所以返回false。
bool CheckCommon(std::vector<long> const& inVectorA, std::vector<long> const& nVectorB)
{
for (auto const& num : inVectorA)
{
auto it = std::find(begin(nVectorB), end(nVectorB), num);
if (it != end(nVectorB))
{
return true;
}
}
return false;
}
Usage of std::set_intersection
is one option. 使用std::set_intersection
是一种选择。 Since the vector's elements are sorted, the code can be simplified to this: 由于向量的元素已排序,因此代码可以简化为:
#include <algorithm>
#include <iterator>
bool CheckCommon( const std::vector< long > &inVectorA, const std::vector< long > &inVectorB )
{
std::vector< long > temp;
std::set_intersection(inVectorA.begin(), inVectorA.end(),
inVectorB.begin(), inVectorB.end(),
std::back_inserter(temp));
return !temp.empty()
}
The drawback is that a temporary vector is being created while the set_intersection
is being executed (but maybe in the future, this can be considered a "feature" if you want to know what elements are common). 缺点是正在执行set_intersection
正在创建临时向量(但是如果你想知道哪些元素是常见的,将来可能会被视为“特征”)。
Your code uses std::binary_search
, whose pre-condition is that (From http://en.cppreference.com/w/cpp/algorithm/binary_search ): 您的代码使用std::binary_search
,其前提条件是(来自http://en.cppreference.com/w/cpp/algorithm/binary_search ):
For
std::binary_search
to succeed, the range[first, last)
must be at least partially ordered, ie it must satisfy all of the following requirements: 要使std::binary_search
成功,范围[first, last)
必须至少部分排序,即它必须满足以下所有要求:
- partitioned with respect to
element < value
orcomp(element, value)
相对于element < value
或comp(element, value)
分区
- partitioned with respect to
!(value < element)
or!comp(value, element)
相对于!(value < element)
或!comp(value, element)
分区- for all elements, if
element < value
orcomp(element, value)
istrue
then!(value < element)
or!comp(value, element)
is alsotrue
对于所有元素,如果element < value
或comp(element, value)
为true
则!(value < element)
或!comp(value, element)
也为true
A fully-sorted range meets these criteria, as does a range resulting from a call to
std::partition
. 完全排序的范围符合这些标准,调用std::partition
产生的范围也是如此。
The sample data you used for testing (as posted at http://ideone.com/XCYdM8 ) do not meet that requirement. 您用于测试的样本数据(在http://ideone.com/XCYdM8上发布)不符合该要求。 Instead of using: 而不是使用:
vectorB.push_back(11116);
vectorB.push_back(11118);
vectorB.push_back(11112);
vectorB.push_back(11120);
vectorB.push_back(11190);
vectorB.push_back(11640);
vectorB.push_back(11740);
if you use a sorted vector like below 如果您使用如下所示的排序向量
vectorB.push_back(11112);
vectorB.push_back(11116);
vectorB.push_back(11118);
vectorB.push_back(11120);
vectorB.push_back(11190);
vectorB.push_back(11640);
vectorB.push_back(11740);
your function will work just fine. 你的功能会很好。
PS The you have designed your code, if the longer std::vector
is sorted, the function will work fine. PS你已经设计了你的代码,如果更长的std::vector
被排序,该函数将正常工作。
PS2 Another option is to sort the longer std::vector
before calling the function. PS2另一种选择是在调用函数之前对较长的std::vector
进行排序。
std::sort(B.begin(), B.end());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.