使用不同的比较函数合并两个排序的双向量
Merge two sorted double vectors using different comparision function
我有两个排序std::vector<double>
容器。现在我需要将两个向量合并到一个新的排序容器中,但有限制, 当且仅当std::fabs(a-b)<1.e-6
成立时,两个值应被视为相等。这个问题在我们的 代码,我正在寻找最整洁的解决方案。
我的第一次尝试是:
std::vector<double> mergeTimeLists(const std::vector<double>& sorted1, const std::vector<double>& sorted2) {
auto cmp = [&](double a, double b)->bool { return std::fabs(a - b) > 1e-6 && a < b; };
std::set<double, decltype(cmp)> set(cmp);
std::copy(sorted1.begin(), sorted1.end(), std::inserter(set, set.begin()));
std::copy(sorted2.begin(), sorted2.end(), std::inserter(set, set.begin()));
std::vector<double> ret;
std::copy(set.begin(), set.end(), std::back_inserter(ret));
return ret;
}
在再次查阅了STL的文档后,我想出了:
std::vector<double> mergeTimeLists1(const std::vector<double>& sorted1, const std::vector<double>& sorted2) {
std::vector<double> ret;
std::merge(sorted1.begin(), sorted1.end(), sorted2.begin(), sorted2.end(), std::back_inserter(ret));
ret.erase(std::unique(ret.begin(), ret.end(), [&](double a, double b)->bool { return std::fabs(a - b) < 1e-6; }),ret.end());
return ret;
}
这是我的测试:
int main(int argc, char** args) {
{
auto ret = mergeTimeLists({ 0,0.1,0.2,0.3,0.34 }, { 0.05,0.10000001 });
std::copy(ret.begin(), ret.end(), std::ostream_iterator<double>(std::cout, " "));
}
std::cout << std::endl;
{
auto ret = mergeTimeLists1({ 0,0.1,0.2,0.3,0.34 }, { 0.05,0.10000001 });
std::copy(ret.begin(), ret.end(), std::ostream_iterator<double>(std::cout, " "));
}
}
有人对改进有一些想法吗?
修订后的问题
似乎,我无法完全清晰和明确地陈述我的问题。事实证明,我真正想要的是略有不同的东西。
假设我有两个排序的std::vector<double>
容器s1
和s2
。我想创建一个新的排序容器s
包含s1
中的所有值和s2
中的一些值,而s2
中的值v
仅包含在s
中当且仅当s1
中没有值u
时,这样std::fabs(u-v)<1e-6
。
因此,我只希望s2
的值在生成的容器s
中,如果s1
中的某些值不太接近。
我很抱歉没有事先这么清楚地说明我的问题,我对到目前为止已经得到的反馈感到非常高兴。也许我还能从这里得到一些想法?
对向量进行排序。 结果也是一个排序向量。
使用std::merge()
是一个良好的开端,但您的示例在两个方面未能达到最佳性能:
- 您忽略了在合并之前在返回的向量中保留容量。
- 您可以在合并过程中插入所有元素,然后在合并后擦除不需要的元素。
第一个是微不足道的:
ret.reserve(std::max(sorted1.size(), sorted2.size()));
第二个可以通过更改给定的输出迭代器来解决std::merge()
。 而不是std::back_inserter(ret)
,创建自己的unique_inserter(ret)
,如下所示:
struct unique_inserter
: std::back_insert_iterator<std::vector<double>>
{
typedef std::back_insert_iterator<std::vector<double>> base;
unique_inserter(std::vector<double>& out) : base(out) {}
unique_inserter& operator=(const double& value)
{
if (container->empty() || std::fabs(container->back() - value) > 1e-6)
container->push_back(value);
return *this;
}
// remove this if not using C++11
unique_inserter& operator=(const double&& value)
{
if (container->empty() || std::fabs(container->back() - value) > 1e-6)
container->push_back(std::move(value));
return *this;
}
};
这类似于std::back_inserter
但如果新值等效于最后一个值,则不执行任何操作。 这样,不需要的值永远不会插入,以后也不需要擦除。
相关文章:
- 查找两个排序向量中共有的元素
- 合并两个排序链表时运行时出错
- 在 C++ 中合并两个排序链表
- 两个排序的链接列表C 的交点
- 合并两个排序的链表
- 合并两个排序的列表 - 不起作用
- 使用不同的比较函数合并两个排序的双向量
- (C++)如何创建一个函数来接收两个排序的链表并返回出现在两个列表中的第三个元素列表
- 比较两个排序的数字向量(性能优先)
- 如何在c++中使用两个排序标准(对于一组对)创建有序集
- 合并两个排序的链接列表
- 在给定两个排序向量的情况下设置减法
- 在C++中合并两个排序的列表
- 将值插入到两个排序不同的 BST 中
- 合并两个排序的链表
- 合并两个排序的单向链表 [错误]
- 将两个排序向量合并到一个排序向量中
- 合并两个排序列表出现运行时错误
- 如何合并两个排序的链表
- 保持两个排序的向量通过指针连接