所以,这与其他答案略有不同。我不能说C++编译器完全是一个“Linux CLI工具”,但是运行
g++ -O3 -march=native -o set_diff main.cpp
(在
main.cpp
中包含以下代码)可以达到效果:
#include<algorithm>
#include<iostream>
#include<iterator>
#include<fstream>
#include<string>
#include<unordered_set>
using namespace std;
int main(int argc, char** argv) {
ifstream keep_file(argv[1]), del_file(argv[2]);
unordered_multiset<string> init_lines{istream_iterator<string>(keep_file), istream_iterator<string>()};
string line;
while (getline(del_file, line)) {
init_lines.erase(line);
}
copy(init_lines.begin(),init_lines.end(), ostream_iterator<string>(cout, "\n"));
}
使用方法很简单,只需运行set_diff B A
(不是A B
,因为B
是nodes_to_keep
),结果差异将被打印到标准输出。
请注意,我已经放弃了一些C++的最佳实践,以使代码更简单。
许多额外的速度优化可以进行(以更多的内存为代价)。对于大型数据集,mmap
也非常有用,但这将使代码变得更加复杂。
由于您提到数据集很大,因此我认为逐行读取nodes_to_delete
可能是降低内存消耗的好主意。如果nodes_to_delete
中有很多重复项,则上面代码中采用的方法不是特别有效。此外,顺序不保留。
为了更方便地复制和粘贴到 bash
中(即跳过创建 main.cpp
),可以使用以下代码:
g++ -O3 -march=native -xc++ -o set_diff - <<EOF
#include<algorithm>
#include<iostream>
#include<iterator>
#include<fstream>
#include<string>
#include<unordered_set>
using namespace std;
int main(int argc, char** argv) {
ifstream keep_file(argv[1]), del_file(argv[2]);
unordered_multiset<string> init_lines{istream_iterator<string>(keep_file), istream_iterator<string>()};
string line;
while (getline(del_file, line)) {
init_lines.erase(line);
}
copy(init_lines.begin(),init_lines.end(), ostream_iterator<string>(cout, "\n"));
}
EOF