C++: check if vector<Class> is subset of vector<Class> -
i have following piece of code. have 2 strings (k1, k2), break tokens using whitespace delimeter (t1, t2). want check if t1 contained in t2. problem issubset(t1, t1) 0 value returned. want avoid using vector<string>
instead of vector<stringref>
, if possible. doing wrong? output should 2 1's 2 0's instead.
#include<string> #include<iostream> #include <time.h> #include <string.h> #include <vector> #include <algorithm> using namespace std; class stringref { private: char const* begin_; int size_; public: int size() const { return size_; } char const* begin() const { return begin_; } char const* end() const { return begin_ + size_; } std::string tostring() { std::string value(begin_); return value; } stringref( char const* const begin, int const size ) : begin_( begin ) , size_( size ) {} bool operator<(const stringref& s) const { return (strcmp(begin(), s.begin()) < 0); } }; /************************************************ * checks if vector b subset of vector * ************************************************/ bool issubset(std::vector<stringref> a, std::vector<stringref> b) { std::sort(a.begin(), a.end()); std::sort(b.begin(), b.end()); return std::includes(a.begin(), a.end(), b.begin(), b.end()); } /************************************************ * split string using delimeter; returns vector * ************************************************/ vector<stringref> split3( string const& str, char delimiter = ' ' ) { vector<stringref> result; enum state { inspace, intoken }; state state = inspace; char const* ptokenbegin = 0; // init satisfy compiler. for( auto = str.begin(); != str.end(); ++it ) { state const newstate = (*it == delimiter? inspace : intoken); if( newstate != state ) { switch( newstate ) { case inspace: result.push_back( stringref( ptokenbegin, &*it - ptokenbegin ) ); break; case intoken: ptokenbegin = &*it; } } state = newstate; } if( state == intoken ) { result.push_back( stringref( ptokenbegin, &str.back() - ptokenbegin ) ); } return result; } int main() { string k1 = "9 10"; string k2 = "9 10 2 3"; vector<stringref> t1 = split3(k1,' '); vector<stringref> t2 = split3(k2,' '); cout<<issubset(t1,t1)<<endl; cout<<issubset(t2,t1)<<endl; return 0; }
edit: ------ corrections -------
changed tostring
to:
std::string tostring() const { std::string value(begin_, size_); return value; }
changed operator<
to: (thanks @mike seymour)
bool operator<(const stringref& s) const { return (std::lexicographical_compare(begin(), end(), s.begin(), s.end())); }
finally, in split3
, changed if block before return statement to:
if( state == intoken ) { result.push_back( stringref( ptokenbegin, &str.back() + 1 - ptokenbegin ) ); }
there issues in code.
result.push_back( stringref( ptokenbegin, &str.back() - ptokenbegin ) );
contains off-by-one error, size of last token short.
return (strcmp(begin(), s.begin()) < 0);
and
std::string value(begin_);
rely on \0
terminated c strings, not using \0
terminated c strings.
std::string tostring() {
should const method.
after resolved of these issue, code worked.
Comments
Post a Comment