C ++: прочитайте набор данных и проверьте, является ли вектор & lt; Class & gt; является подмножеством вектора & lt; Class & gt;

У меня есть следующий кусок кода. Код создает векторный набор данных, каждый элемент которого является вектором. Это также создает вектор S.

Я хочу проверить, какой вектор из набора данных содержит вектор S. По-видимому, я делаю что-то не так, потому что для следующего примера,
Набор данных:
а б в
д
а б д

и S:
а б

должно вывести: 0 2

и для меня это печатает: 0 1 2

#include <iostream>
#include <fstream>
#include <sstream>
#include <string.h>
#include <string>
#include <time.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_; }

StringRef( char const* const begin, int const size )
: begin_( begin )
, size_( size )
{}

bool operator<(const StringRef& obj) const
{
return (strcmp(begin(),obj.begin()) > 0 );
}

};/************************************************
* Checks if vector B is subset of vector A     *
************************************************/

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());
}vector<StringRef> split3( string const& str, char delimiter = ' ' )
{
vector<StringRef>   result;

enum State { inSpace, inToken };

State state = inSpace;
char const*     pTokenBegin = 0;    // Init to satisfy compiler.
for(auto it = str.begin(); it != 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() {

vector<vector<StringRef> > Dataset;
vector<vector<StringRef> > S;

ifstream input("test.dat");
long count = 0;
int sec, lps;
time_t start = time(NULL);

cin.sync_with_stdio(false); //disable synchronous IO

for( string line; getline( input, line ); )
{
Dataset.push_back(split3( line ));
count++;
};
input.close();
input.clear();

input.open("subs.dat");
for( string line; getline( input, line ); )
{
S.push_back(split3( line ));
};for ( std::vector<std::vector<StringRef> >::size_type i = 0; i < S.size(); i++ )
{
for(std::vector<std::vector<StringRef> >::size_type j=0; j<Dataset.size();j++)
{

if (isSubset(Dataset[j], S[i]))
{
cout << j << " ";
}

}
}

sec = (int) time(NULL) - start;
cerr << "C++   : Saw " << count << " lines in " << sec << " seconds." ;
if (sec > 0) {
lps = count / sec;
cerr << "  Crunch speed: " << lps << endl;
} else
cerr << endl;

return 0;
}

0

Решение

Ваш StringRef Тип опасен, потому что он содержит const char * указатель, но нет понятия собственности. Таким образом, указатель может быть признан недействительным в какой-то момент после создания объекта.

И действительно, это то, что происходит здесь: у вас есть одна строка (line) и создать StringRefс указателями на его внутренние данные. Когда строка позже изменяется, эти указатели становятся недействительными.

Вы должны создать vector<std::string> вместо этого, чтобы предотвратить эту проблему.

2

Другие решения


По вопросам рекламы [email protected]