C++ 集_差、集_交和集_并的就地版本
我实现了C++ 集_差、集_交和集_并的就地版本,c++,algorithm,stl,C++,Algorithm,Stl,我实现了set\u union、set\u intersection和set\u difference的版本,它们接受一个已排序的容器和一个已排序的范围(不能在容器内),并将操作结果写入容器 template<class Container, class Iter> void assign_difference(Container& cont, Iter first, Iter last) { auto new_end = std::set_difference( /
set\u union
、set\u intersection
和set\u difference
的版本,它们接受一个已排序的容器和一个已排序的范围(不能在容器内),并将操作结果写入容器
template<class Container, class Iter>
void assign_difference(Container& cont, Iter first, Iter last)
{
auto new_end = std::set_difference( // (1)
cont.begin(), cont.end(), first, last, cont.begin());
cont.erase(new_end, cont.end());
}
template<class Container, class Iter>
void assign_intersection(Container& cont, Iter first, Iter last)
{
auto new_end = std::set_intersection( // (2)
cont.begin(), cont.end(), first, last, cont.begin());
cont.erase(new_end, cont.end());
}
template<class Container, class Iter>
void assign_union(Container& cont, Iter first, Iter last)
{
auto insert_count = last - first;
cont.resize(cont.size() + insert_count); // T must be default-constructible
auto rfirst1 = cont.rbegin() + insert_count, rlast1 = cont.rend();
auto rfirst2 = std::make_reverse_iterator(last);
auto rlast2 = std::make_reverse_iterator(first);
rlast1 = std::set_union( // (3)
rfirst1, rlast1, rfirst2, rlast2, cont.rbegin(), std::greater<>());
cont.erase(std::copy(rlast1.base(), cont.end(), cont.begin()), cont.end());
}
模板
无效分配(容器和容器,Iter优先,Iter最后)
{
自动新建结束=标准::设置差异(//(1)
cont.begin(),cont.end(),first,last,cont.begin());
继续擦除(新的结束,继续结束());
}
模板
无效分配交叉点(容器和容器,Iter优先,Iter最后)
{
自动新建端点=标准::设置交点(//(2)
cont.begin(),cont.end(),first,last,cont.begin());
继续擦除(新的结束,继续结束());
}
模板
无效分配联合(容器和容器,Iter优先,Iter最后)
{
自动插入计数=最后一次-第一次;
cont.resize(cont.size()+insert_count);//T必须是默认可构造的
自动rfirst1=cont.rbegin()+插入计数,rlast1=cont.rend();
auto rfirst2=std::make_reverse_迭代器(last);
auto rlast2=std::make_reverse_迭代器(第一);
rlast1=std::set_并集(//(3)
rfirst1,rlast1,rfirst2,rlast2,cont.rbegin(),std::greater());
cont.erase(std::copy(rlast1.base()、cont.end()、cont.begin()、cont.end());
}
目标是:
- 如果容器具有足够的容量来保存结果,则不执行分配
- 否则,只执行一次分配,为容器提供容纳结果的容量
设置交叉
和设置差异
要求结果范围不与其中一个输入范围重叠。
但是,是否有STL实现会破坏代码?
如果您的答案是肯定的,请提供三种使用的STL算法中破坏代码的一种的一致性实现。一致性实现可以检查
集合交集的参数1和5是否相等,以及它们是否格式化了您的硬盘
如果您违反了要求,您的程序行为不受标准约束;你的程序格式不正确
在某些情况下,UB可能值得承担风险和成本(审核所有编译器更改和程序集输出)。我看不出这有什么意义;写你自己的。std库提出的任何奇特的优化都可能会在您违反需求时导致问题,正如您所注意到的,这种幼稚的实现非常简单。我使用的经验法则是不要在您正在迭代的容器上编写。一切都可能发生。总的来说,这很奇怪
正如@Yakk所说,这听起来很糟糕。就这样。要从代码库中删除的内容可以让您平静地入睡
如果您确实需要这些函数,我建议您自己编写内部循环(例如:std::set_intersection
)以处理算法工作所需的约束
我不认为寻找一个STL实现是正确的方法。这听起来不像是一个长期的解决方案。从长远来看:标准应该是你的参考,正如有人已经指出的,你的解决方案似乎没有正确处理它
我的2美分即使今天的一致性实现没有破坏代码,如果标准中没有保证,那么简单地升级编译器可能会导致代码破坏。甚至不同的优化设置或任何其他编译器标志。我认为您必须提供自己的实现来确保tbh。这些算法的实现只需要几行代码,因此,您可以编写一个破坏代码的标准。我的标准副本中有以下所有这些算法的文本:要求:生成的范围不得与原始范围重叠。
我认为您不能保证这是有效的。