0

我目前正在尝试创建一个 C++ 函数来连接两个管道分割文件,其中一个或两个关键字段上有超过 10.000.000 条记录。

字段看起来像



    P2347|John Doe|C1234
    P7634|Peter Parker|D2344
    P522|Toni Stark|T288



    P2347|Bruce Wayne|C1234
    P1111|Captain America|D534
    P522|Terminator|T288

要加入字段 1 和 3,预期输出应显示:



    P2347|C1234|John Doe|Bruce Wayne
    P522|T288|Toni Stark|Terminator

我目前正在考虑的是使用集合/数组/向量来读取文件并创建类似的内容:



    P2347|C1234>>John Doe
    P522|T288>>Toni Stark



    P2347|C1234>>Bruce Wayne
    P522|T288>>Terminator

然后使用滑动第一部分作为键并将其与第二个集合/向量/数组匹配。

我目前拥有的是:读入第一个文件并逐行匹配第二个文件。它需要整行并匹配它:



    #include iostream>
    #include fstream>
    #include string>
    #include set>
    #include ctime>
    using namespace std;

    int main()
    {

        clock_t startTime = clock();

        ifstream inf("test.txt");
        set lines;
        string line;
        for (unsigned int i=1; std::getline(inf,line); ++i)
            lines.insert(line);

        ifstream inf2("test2.txt");

        clock_t midTime = clock();

        ofstream outputFile("output.txt");  
        while (getline(inf2, line))
        {
            if (lines.find(line) != lines.end())
                outputFile > a;
        return 0;

}

我很高兴有任何建议。如果有更好(更快)的方法,我也很乐意改变整个概念。速度至关重要,因为可能有超过 1000 万条记录。

编辑:另一个想法是拿一张地图,把钥匙当作钥匙——但这可能会慢一点。有什么建议么?

非常感谢您的帮助!

4

1 回答 1

0

我尝试了多种方法来完成这项任务,到目前为止都没有效率:

将所有内容读入一个集合并将关键字段解析为一种格式:keys >> values 模拟数组类型集合。解析花费了很长时间,但内存使用率保持相对较低。未完全开发的代码:



        #include \
        #include \
        #include \
        #include \
        #include \
        #include \
        #include \
        std::vector &split(const std::string &s, char delim, std::vector &elems) {
        std::stringstream ss(s);
        std::string item;
        while (std::getline(ss, item, delim)) {
            elems.push_back(item);
        }
        return elems;
    }


    std::vector split(const std::string &s, char delim) {
        std::vector elems;
        split(s, delim, elems);
        return elems;
    }

    std::string getSelectedRecords(std::string record, int position){

        std::string values;
        std::vector tokens = split(record, ' ');




        //get position in vector
        for(auto& s: tokens)
            //pick last one or depending on number, not developed
            values = s;

        return values;
    }

    int main()
    {

        clock_t startTime = clock();

        std::ifstream secondaryFile("C:/Users/Batman/Desktop/test/secondary.txt");
        std::set secondarySet;
        std::string record;

        for (unsigned int i=1; std::getline(secondaryFile,record); ++i){
            std::string keys = getSelectedRecords(record, 2);
            std::string values = getSelectedRecords(record, 1);
            secondarySet.insert(keys + ">>>" + values);
        }

        clock_t midTime = clock();

        std::ifstream primaryFile("C:/Users/Batman/Desktop/test/primary.txt");
        std::ofstream outputFile("C:/Users/Batman/Desktop/test/output.txt");

        while (getline(primaryFile, record))
        {
            //rewrite find() function to go through set and find all keys (first part until >> ) and output values
            std::string keys = getSelectedRecords(record, 2);

            if (secondarySet.find(keys) != secondarySet.end())
                outputFile > a;
        return 0;
        }

它当前使用空间划分而不是管道划分,但这不应该是一个问题。读取数据非常快,但解析它需要大量时间

另一种选择是采用多图。类似的概念,关键字段指向值,但这个概念非常低且内存密集。



    #include \
    #include \
    #include \
    #include \
    #include \
    #include \
    #include \

    int main()
    {


    std::clock_t startTime = clock();

    std::ifstream inf("C:/Users/Batman/Desktop/test/test.txt");
    typedef std::multimap Map;
    Map map;

    std::string line;

    for (unsigned int i=1; std::getline(inf,line); ++i){
        //load tokens into vector
        std::istringstream buffer(line);
        std::istream_iterator beg(buffer), end;
        std::vector tokens(beg, end);
        //get keys
        for(auto& s: tokens)
            //std::cout >>" second;
            outputFile > a;
    return 0;
    }

进一步的想法是:在导入数据时将管道分割的文件分成不同的文件,每列一列。这样我就不必解析任何东西,但可以单独阅读每一列。

编辑:使用递归拆分函数优化了第一个示例。对于 100.000 条记录,仍然 > 30 秒。希望看到更快加上实际的 find() 函数仍然缺失。

有什么想法吗?谢谢!

于 2013-10-12T19:35:52.417 回答