简体   繁体   中英

Are all elements of `x` present in `y` (sorted vectors)?

Let x and y be two sorted vectors. I would like to figure out which of the three is correct

A. All elements of `y` are present in `x`
B. Some but not all elements of `y` are present in `x`
C. No element of `y` is present in `x`
U. Undefined (because `y` is empty)

A naive way to achieve this is with

template<typename T>
char f(std::vector<T> x, std::vector<T> y)
{
    if (y.size() == 0)
    {
        return 'U';
    }

    bool whereAnyElementFound = false;
    bool whereAnyElementNotFound = false;
    for (T& y_element : y)
    {
        bool isElementFound = std::find(x.begin(),x.end(),y_element) != x.end();
        if (isElementFound)
        {
            whereAnyElementFound = true;
            if (whereAnyElementNotFound)
            {
                return 'B';
            }
        } else
        {
            whereAnyElementNotFound = true;
            if (whereAnyElementFound)
            {
                return 'B';
            }
        }
    }
    if (whereAnyElementFound)
    {
        return 'A';
    } else if (whereAnyElementNotFound)
    {
        return 'C';
    }
    abort();
}

The function correctly match the following inputs to outputs

inputs: x = {1,2,4,5} y = {2,5}
output: A

inputs: x = {1,2,4,5} y = {2,7}
output: B

inputs: x = {1,2,4,5} y = {6,7}
output: C

inputs: x = {1,2,4,5} y = {}
output: U

However, this method does not take advantage of the fact that both vectors are sorted. How can this function made faster for larger vectors?

For the cost of O(N) additional space you can use std::set_intersection . It has O(2(N1+N2-1)) complexity and generates a "set" of all the common elements between the two vectors. You can then check that new "set"'s size to figure out A, B, C and U.

int main()
{
    std::vector<int> v1{1,2,3,4,5,6,7,8};
    std::vector<int> v2{5,7,9,10};

    std::vector<int> intersection;

    std::set_intersection(v1.begin(), v1.end(),
                          v2.begin(), v2.end(),
                          std::back_inserter(intersection));
    if (intersection.size() == v2.size() && v2.size() > 0)
        std::cout << "A";
    else if (intersection.size() > 0)
        std::cout << "B";
    else if (intersection.size() == 0 && v2.size() > 0)
        std::cout << "C";
    else
        std::cout << "U";
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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