已知文件中的对象号集合,为了求出新文件相对于老文件的增删改,只需要求出对象号的交集和差集即可。
STL 算法已有 set_interection 和 set_difference 用于计算交集和差集,但是如果直接使用 STL 算法的话,必须调用 set_interection 1次,以及 set_difference 2次,总共需要遍历3次。为了降低时间复杂度,可以在一个函数里把交集和差集都求出来,这样只需要遍历一次就可以了。
代码如下:
// 传入的 inter,del,add 的 size 必须是 0.
void GetIntersectionAndDifferences(const std::vector<int>& lhs, const std::vector<int>& rhs,
std::vector<int>& inter, std::vector<int>& del, std::vector<int>& add) {
if (lhs.empty() || rhs.empty() ||
lhs.back() < rhs.front() || rhs.back() < lhs.front()) {
del = lhs;
add = rhs;
return;
}
inter.reserve(std::min(lhs.size(), rhs.size()));
del.reserve(lhs.size());
add.reserve(rhs.size());
auto lhs_iter = lhs.begin();
auto rhs_iter = rhs.begin();
while (lhs_iter != lhs.end() && rhs_iter != rhs.end()) {
if (*lhs_iter < *rhs_iter) {
del.push_back(*lhs_iter);
++lhs_iter;
} else if (*rhs_iter < *lhs_iter) {
add.push_back(*rhs_iter);
++rhs_iter;
} else {
inter.push_back(*lhs_iter);
++lhs_iter;
++rhs_iter;
}
}
for (; lhs_iter != lhs.end(); ++lhs_iter)
del.push_back(*lhs_iter);
for (; rhs_iter != rhs.end(); ++rhs_iter)
add.push_back(*rhs_iter);
inter.reserve(inter.size());
del.reserve(del.size());
add.reserve(add.size());
}