重复的筛选器列表 - 列出重复数据删除

时间:2014-11-10 01:22:09

标签: c++ arrays performance merge array-merge

我有一些分散在几个文件中的单词列表,我需要一种快速方法将它们全部合并到一个文件中。我想在合并时删除重复项,以便最终列表不包含单个单词的多个实例。

示例:

文本文件list_a.txt说明如下:

apple
pear
peach

文本文件list_b.txt说明如下:

foo
bar
peach
car

合并后,输出文件应该说:

apple
pear
peach
foo
bar
car

请注意,list_a.txtlist_b.txt都包含单词peach,但它只在输出文件中出现一次。

这是我正在使用的代码:

int main()
{
    string myList = "";
    string myFiles[] = {"list_a.txt", "list_b.txt"};
    string line;
    int iterationsSinceSleep = 0;
    size_t length = sizeof(myFiles)/sizeof(myFiles[0]);
    for(unsigned int i = 0; i < length; i++){
        cout<<"Starting " << myFiles[i] << endl;
        ifstream myfile((string("C:/words/").append(myFiles[i])).c_str());
        if (myfile.is_open())
        {
            while ( getline (myfile,line) ){
                string trimmedLine = trim(line);
                if(myList.find(trimmedLine) == string::npos){
                    myList.append(trimmedLine + '\n');
                }

                iterationsSinceSleep++;
                iterationsSinceSleep %= 10000;
                // Save the CPU!
                if(iterationsSinceSleep == 0) Sleep(10);

            }
            myfile.close();
        }else{
            cout << "Could not open & process " << myFiles[i] << endl;
        }
        Sleep(75); // Save the CPU!
        iterationsSinceSleep = 0;
    }

    // write to the file
    ofstream myfile ("C:/words/merged/final.txt");
    if (myfile.is_open())
    {
        cout<<"Writing filtered list"<<endl;
        myfile << myList;
        myfile.flush();
        myfile.close();
    }else{
        cout<<"Could not save filtered list."<<endl;
    }



    return 0;
}

这适用于较小的列表/文件,但我的一个列表有几百万行。

我需要一种方法来使这段代码运行良好,即使它必须处理数百万行的几个文件。

我改进这个的第一个想法是使用数组或向量而不是字符串来存储唯一的行。但是,这两种方法都有优点和缺点。

使用数组的优点:

  • 更快的比较检查(我认为)
  • 访问更快的元素

使用数组的缺点:

  • 重新分配以插入新字符串可能会很慢
  • 程序必须跟踪数组的长度(不是一个大问题,而是一个因素)

使用矢量的优点:

  • 动态添加元素
  • 内置搜索功能

使用向量的缺点:

  • 将元素插入向量很慢(所以我已阅读)
  • 我认为矢量有更多的开销。

任何人都可以提供改进此代码并更有效地编写代码的建议吗?速度是一个主要问题,但我还需要考虑内存消耗。

提前谢谢。

1 个答案:

答案 0 :(得分:1)

使用std::set。集合不允许重复输入。尝试类似:

std::set<std::string> mySet;
...
mySet.insert(trimmedString);
...
for (auto &&str : mySet)
   myFile << str;

注意:我在这里输入了这个,所以可能会有一些拼写错误。

另请注意:这将对输出进行排序,不确定是否需要。