简体   繁体   English

检查两个元素在C ++中是否具有公共元素

[英]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;
}

DEMO DEMO

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 or comp(element, value) 相对于element < valuecomp(element, value)分区
    • partitioned with respect to !(value < element) or !comp(value, element) 相对于!(value < element)!comp(value, element)分区
    • for all elements, if element < value or comp(element, value) is true then !(value < element) or !comp(value, element) is also true 对于所有元素,如果element < valuecomp(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.

相关问题 是否可以编写c ++模板/宏来检查两个函数是否具有相同的签名 - Is it possible to write c++ template/macros to check whether two functions have the same signatures c++中如何检查用户输入的数组元素是否排序 - How to check whether array elements entered by user are sorted or not in c++ C ++检查类对象是否包含某个元素 - C++ check whether a classes object contains a certain element 使用C++检查两个字符串是否为字谜 - Check whether two strings are anagrams using C++ 检查C++中的两个对象是否属于同一个class - check whether two objects belongs to same class in C++ 确定两个 integer 列表是否包含公共元素(c++) - Deciding two integer list contains common elements or not (c++) 找出两个范围(其中一个已排序)是否具有一个公共元素 - Finding out whether two ranges (one of them is sorted) have a common element 是否可以使用`std :: set_intersection`来检查两个集合是否有任何共同的元素? - Is it possible to use `std::set_intersection` to check if two sets have any element in common? 如何在C ++中检查集合是否包含某个范围内的元素 - how to check whether a set has element(s) in certain range in C++ 将向量中指向元素的指针设置为null,然后检查指针是否为null(C ++) - Set pointer to element in vector to null, then check whether pointer is null (C++)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM