C++:读取数据集并检查向量是否<Class>是向量的<Class>子集

C++: read dataset and check if vector<Class> is subset of vector<Class>

本文关键字:向量 Class gt lt 子集 是否 读取 数据集 检查 C++      更新时间:2023-10-16

我有以下一段代码。该代码创建一个矢量数据集,其每个元素都是一个矢量。它还创建一个向量 S。

我想检查数据集的哪个向量包含 S 的向量,显然我做错了什么,因为对于以下示例,数据集为:
阿 b c
一 d
阿 b d

和 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;
}

您的StringRef类型很危险,因为它包含一个const char *指针,但没有所有权的概念。因此,指针可能会在构造对象后的某个时间点失效。

事实上,这就是这里发生的事情:你有一个字符串(line(,并创建带有指向其内部数据的指针的StringRef。稍后修改字符串时,这些指针将失效。

您应该改为创建一个vector<std::string>来防止此问题。