2016-06-01 7 views
9

में मेरे पास std::set<int> और std::vector<int> (v) है। वेक्टर को क्रमबद्ध/अनूठा होने की गारंटी है। मैं जानना चाहता हूं कि वी के सभी तत्व एस में हैं (या केवल वी के पहले तत्व पर रोकें)। मैं वी को एक सेट में परिवर्तित कर सकता हूं और == परीक्षण कर सकता हूं, लेकिन कंटेनर प्रकार को बदलने के बिना कोई और तरीका है?सी ++: कंटेनर 1 से कोई तत्व नहीं मिला कंटेनर 2

+0

एक पाश, 'std :: find_if()' और एक भेड़ का बच्चा? –

+5

'std :: mismatch' के बारे में कैसे? –

+0

'std :: set_difference'? –

उत्तर

9

std::includes एल्गोरिदम के बारे में क्या है?

यहाँ एक छोटी उपयोग उदाहरण है:

vector<int> v1 { 1, 2, 4, 8 }; 
vector<int> v2 { 1, 2, 3, 8 }; 
set<int> s { 0, 1, 2, 4, 8, 16 }; 
cout << includes(s.begin(), s.end(), v1.begin(), v1.end()) << endl; 
cout << includes(s.begin(), s.end(), v2.begin(), v2.end()) << endl; 

आउटपुट:

1 
0 
2

मुझे लगता है कि आप std::set::count या std::unordered_set::count लिए देख रहे हैं:

if(v.size() > s.size()) 
{ 
    // since v has unique values 
    // v is not subset of s 
    // if you need to find a first element of v not in s 
    // you need to run the loop below anyway 
} 
for(auto i : v) 
{ 
    if(!s.count(i)) 
    { 
     // i not in s 
    } 
} 

आप वी के सभी तत्वों की जरूरत है नहीं रों में, बस का उपयोग std::set_difference

+0

यह ओ (एन लॉग एम) है, लेकिन अन्य विकल्प सुझाए गए हैं ओ (एन + एम), जो बेहतर है। –

+0

क्या हम मान सकते हैं कि एस std :: unordered_set है? फिर, यह ओ (एन) – lllllllllll

+0

सच है, हालांकि ओपी निर्दिष्ट 'सेट'। –

1

std::set<int> आदेश दिया की जाएगी। यदि std::vector<int> ऑर्डर करने की गारंटी है और इसमें अद्वितीय मान हैं, तो आप दोनों को दोहरा सकते हैं और आइटम के मानों की तुलना कर सकते हैं।

std::set<int> s = {...}; 
std::vector<int> v = {...}; 

// Default answer. If v.size() > s.size(), the answer is 
// definitely false. Otherwise, assume the answer to be true. 
bool ans = (v.size() <= s.size()); 

auto si = s.begin(); 
auto vi = v.begin(); 

// We need to check for si != s.end() 
for (; ans == true && vi != v.end() && si != s.end(); ++si) 
{ 
    if (*si == *vi) ++vi; 
    else if (*si > *vi) ans = false; 
} 
if (vi != v.end()) ans = false; 
// ... 
return ans; 
0

हे (एन) समाधान:

#include <iostream> 
#include <set> 
#include <vector> 

bool incCase(std::set<int> &s, std::vector<int> &v) 
{ 
    if(v.size() > s.size()) 
     return false; 

    auto si = s.begin(); 

    for(int& vv : v) 
    { 
     for(;;si++) 
     { 
      if(si==s.end() || *si>vv) 
       return false; 
      if(*si==vv) 
      { 
       si++; 
       break; 
      } 
     } 
    } 

    return true; 
} 

int main() 
{ 
    std::set<int> s { 0, 1, 2, 4, 8, 16 }; 
    std::vector< std::vector<int> > vv { 
     { 0, 1, 2, 4, 8, 16 }, 
     { 0, 2 }, 
     { 4, 16 }, 
     { 2, 8, }, 
     { 4}, 
     { 1, 4, 16 }, 
     { 0, 2, 8}, 
     { }, 
     { -1, 1, 2, 4, 8, 16 }, 
     { 0, 1, 2, 4, 8, 32 }, 
     { 0, 2, 3 }, 
     { 4, 5, 16 }, 
     { 3, 8, }, 
     { 5}, 
     { 1, 5, 16 }, 
     { 0, 3, 8}, 
    }; 

    int i = 1; 
    for(auto &v : vv) 
    { 
     std::cout<< i++ << (incCase(s,v)?" = True":" = False") << std::endl; 
    } 
} 
संबंधित मुद्दे