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

Filter Lists for Repeats - List Deduplication

本文关键字:数据 删除 列表 筛选 -列      更新时间:2023-10-16

我有一些单词列表分布在几个文件中,我需要一种快速的方法将它们合并到一个文件中。我希望在合并时删除重复项,这样最终列表就不会包含单个单词的多个实例。

示例:

文本文件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;
}

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

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

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

使用阵列的优点:

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

使用阵列的缺点:

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

使用矢量的优点:

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

使用矢量的缺点:

  • 在向量中插入元素很慢(所以我已经读过了)
  • 我想矢量会有更多的开销

有人能为改进这段代码并提高编写效率提供建议吗?速度是一个主要问题,但我也需要考虑内存消耗。

提前谢谢。

使用std::set。集合不允许重复条目。试试类似的东西:

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

注意:我刚刚在这里打了这个,所以可能有一些打字错误。

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