【发布时间】:2015-01-06 06:12:49
【问题描述】:
我有一些分布在多个文件中的单词列表,我需要一种快速的方法将它们全部合并到一个文件中。我想在合并时删除重复项,以便最终列表不包含单个单词的多个实例。
示例:
文本文件list_a.txt 内容如下:
apple
pear
peach
文本文件list_b.txt 内容如下:
foo
bar
peach
car
合并后,输出文件应显示:
apple
pear
peach
foo
bar
car
请注意,list_a.txt 和 list_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;
}
这适用于较小的列表/文件,但我的一个列表有几百万行。
我需要一种方法让这段代码运行良好,即使它必须处理数百万行的多个文件。
我改进这一点的第一个想法是使用数组或向量而不是字符串来存储唯一行。但是,这两种方法各有优缺点。
使用数组的优点:
- 更快的比较检查(我认为)
- 更快的元素访问
使用数组的缺点:
- 重新分配以插入新字符串可能会很慢
- 程序必须跟踪数组的长度(不是大问题,而是一个因素)
使用向量的优点:
- 动态添加元素
- 内置搜索功能
使用向量的缺点:
- 向向量中插入元素很慢(所以我读过)
- 我认为向量的开销更大。
任何人都可以提供改进此代码并更有效地编写它的建议吗?速度是一个主要问题,但我还需要考虑内存消耗。
提前谢谢你。
【问题讨论】:
-
不要使用数组。如果您确实存储它,请使用不允许重复的数据结构,2 只鸟 1 块石头。
-
我认为 trie 结构可以很好地处理这类事情,它可能会产生很大的内存开销,具体取决于您的实现方式,但速度非常快,特别是在单词非常大的情况下
-
好吧,例如向量的分配方案是开箱即用的。你可以通过复制来做同样的事情,但问题就来了——为什么在已经完成的时候还要这样做?
-
阅读vector 以了解向量的分配。
-
@SpencerGrantDoak 对不起我的意思很短,平均单词的长度决定了树的高度,我会更新我的评论
标签: c++ arrays performance merge array-merge