tags:

views:

80

answers:

5

Hi,

I have a number of vectors of strings each containing dates. As a simple example vector A of size 2 might contain:

A[0] = "01-Jul-2010"; 
A[1] = "03-Jul-2010";

while a second vector B of size 3 might contain:

B[0] = "02-Jul-2010";
B[1] = "03-Jul-2010"; 
B[2] = "04-Jul-2010";  

I'd like to form a vector C which contains the 'union' of the element in A and B:

C[0] = "01-Jul-2010";
C[1] = "02-Jul-2010";
C[2] = "03-Jul-2010";
C[3] = "04-Jul-2010"; 

When combining A and B I don't want any repeated dates so each element of C must be unique. Is there any in-built/stl (or Boost library) function I can call that will do this?

Thanks!

+1  A: 

You can use a set (but not a multiset) as an (intermediate) container instead of a vector. This strips any ordering you may want to keep, though.

You can also use std::unique, std::remove_if, or std::set_union (assuming the inputs are sorted).

strager
The dates will need to be in order.
Wawel100
+5  A: 

There is a set_union function in STL to find the union of two (lexicographically) sorted sequences. Assuming A and B are already sorted,

#include <algorithm>
#include <iterator>
#include <vector>
#include <string>

...

std::vector<std::string> C;
std::set_union(A.begin(), A.end(), B.begin(), B.end(), std::back_inserter(C));

If A and B are sorted by date, you need to supply that date-comparing function / functor, e.g.

bool is_earlier(const std::string& first_date, const std::string& second_date) {
   // return whether first_date is earlier than second_date.
}

...

std::set_union(A.begin(), A.end(), B.begin(), B.end(),
               std::back_inserter(C), is_earlier);
KennyTM
Note that _sorted_ in this case means _lexically sorted_, not sorted by date (so, "01-Aug-2010" would come before "02-Jul-2010").
James McNellis
@James: If it is sorted by date, we could supply the 6th parameter.
KennyTM
@KennyTM: I take it that, by "6th parameter", you mean a comparison function or functor? It might be well to put this into your answer in more detail, because I think we may be losing Wawel100 at this point.
David Thornley
+1  A: 

I think you want an STL set. That'll ensure that you don't have duplicates.

Skilldrick
A: 

Possiblities:

  1. Use a set
  2. Use unique_copy
zr
A: 

If set is not applicable std::unique is also possible:

   std::vector<std::string> A;
   std::vector<std::string> B;
   std::vector<std::string> C;

   A.resize (2u);
   B.resize (3u);

   A[0] = "01-Jul-2010";  
   A[1] = "03-Jul-2010"; 

   B[0] = "02-Jul-2010"; 
   B[1] = "03-Jul-2010";  
   B[2] = "04-Jul-2010";   

   C.reserve (5u);

   std::copy (
      A.begin (),
      A.end (),
      std::back_inserter (C)
      );

   std::copy (
      B.begin (),
      B.end (),
      std::back_inserter (C)
      );

   // std::unique requires sorted vector
   std::sort (C.begin(), C.end());
   C.erase (
      std::unique (C.begin(), C.end()),
      C.end ()
      );
FuleSnabel