23

I was wondering is there any function to compare 2 string vectors to return the number of different(or the same) elements? Or i have to iterate over both of them and test item by item.
Thanks.

Adrian
  • 19,440
  • 34
  • 112
  • 219

4 Answers4

46
std::sort(v1.begin(), v1.end());
std::sort(v2.begin(), v2.end());
std::vector<string> v3;
std::set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(v3));

Or, if you don't want to sort:

std::set<string> s1(v1.begin(), v1.end());
std::set<string> s2(v2.begin(), v2.end());
std::vector<string> v3;
std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), std::back_inserter(v3));

You may want to use a multiset if there could be duplicates in a vector.

relaxxx
  • 7,566
  • 8
  • 37
  • 64
Erik
  • 88,732
  • 13
  • 198
  • 189
  • 1
    OK, just need to add #include #include – Jean-Christophe Blanchard Mar 12 '16 at 00:10
  • For `std::sort` you need to be certain v1 & v2 are not `const` and have a `operator<` implemented, which cannot be guaranteed in all situations. – jaques-sam Jan 04 '22 at 13:24
  • if instead of a string is a class/struct, what std::methd must be implemented in the class to make it working with set_intersection? is that std::less or something? would it be possible to edit the answer adding an example with a class/struct type instead of a string? thanks – Raffaello Aug 31 '22 at 22:56
5

I don't know of an existing function but writing one yourself shouldn't be too much trouble.

int compare(const vector<string>& left, const vector<string>& right) {
  auto leftIt = left.begin();
  auto rightIt = right.begin();
  auto diff = 0;
  while (leftIt != left.end() && rightIt != right.end()) {
    if (*leftIt != *rightIt) {
      diff++;
    }
    leftIt++;
    rightIt++;
  }

  // Account for different length vector instances
  if (0 == diff && (leftIt != left.end() || rightIt != right.end())) {
    diff = 1;
  }

  return diff;
}

Notes

  • Omitted std:: prefix for brevity
  • This function needs to be updated if it should handle vector<string> instances of different lengths
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • Thanks, i thought i need to implement one...btw about your code, is there any specific reason you use auto for your local variables ? :) never saw auto been used until now – Adrian Mar 07 '11 at 22:15
  • @vBx, In C++0x `auto` is re purposed for type inference. In the `auto` uses above the compiler can infer the type for me so I don't have to write out the full `vector::const_iterator` for both iterators. It's very similar to C#'s `var` keyword – JaredPar Mar 07 '11 at 22:17
  • We can do better with count_if() can we. – Martin York Mar 07 '11 at 22:17
  • @Martin York, wouldn't `count_if` require the two `vector` implementations be combined into 1? I believe `count_if` can only operate on a single iterator range. True the predicate could be a mutating lambda which advanced the second iterator but that feels wrong. – JaredPar Mar 07 '11 at 22:19
  • the entire body of this function could be replaced with "return left == right;" – Tom Sirgedas Mar 07 '11 at 22:45
  • @TomSirgedas Wouldn't that just return whether or not the vectors are equal? –  Jan 27 '17 at 11:29
  • Yeah, `return left == right` would only return 0 or 1, but the function can return larger values, so my comment is wrong. – Tom Sirgedas Jan 27 '17 at 22:07
5

Have a look at set_difference() and set_intersection(). In both cases you need to have your containers sorted beforehand.

Morten Kristensen
  • 7,412
  • 4
  • 32
  • 52
2
if (vector1 == vector2)
{
    DoSomething();
}

The content will be compared from both vectors as per the below link documentation:

Compares the contents of two vectors.

1-2) Checks if the contents of lhs and rhs are equal, that is, they have the same number of elements and each element in lhs compares equal with the element in rhs at the same position.

https://en.cppreference.com/w/cpp/container/vector/operator_cmp

Build Succeeded
  • 1,153
  • 1
  • 10
  • 24