alf*_*lfC 3 c++ boost boost-icl
Boost.ICL的interval_map
有两种行为:+=
和insert
。两者在不同的上下文中都是有用的。第一个将两个现有间隔的公共交点处的值相加。第二种方法仅在先前未分配的间隔中引入新值(在先前分配的间隔中保留值)。
但是,我需要一种与众不同的行为,这样,在下面的示例中,(1.,2.)->1 , (2.5,3.)->3, (3.,5.)->2
我得到了期望的,而不是得到了不需要的间隔图(1.,2.)->1 , (2.5,5.)->3
。
也就是说,新插入的值替换了旧值吗?我如何声明interval_map
要获得替换行为?
#include<boost/icl/interval_map.hpp>
int main(){
boost::icl::interval_map<double, int> joined_map;
joined_map.insert( std::make_pair(
boost::icl::interval<double>::open(1., 2.),
1
));
joined_map.insert( std::make_pair(
boost::icl::interval<double>::open(3., 5.),
2
));
joined_map.insert( std::make_pair(
boost::icl::interval<double>::open(2.5, 5.),
3
)); // this line doesn't replace the old value 2, it keeps it.
}
Run Code Online (Sandbox Code Playgroud)
奖金:那boost::icl::map
应该做什么?如何使用?
编辑1:这是使用C ++ 11的更明确和简化的示例代码
#include<boost/icl/interval_map.hpp>
#include<iostream>
namespace icl = boost::icl;
using interval = icl::interval<double>;
int main(){
icl::interval_map<double, int> joined_map;
joined_map.insert({interval::open(1., 2.), 1});
joined_map.insert({interval::open(3., 5.), 2});
joined_map.insert({interval::open(2.5, 5.), 3});
// ^^^^ this line doesn't replace the old value 2! it keeps it.
for(auto e: joined_map) std::cout << e.first <<' '<< e.second <<'\n';
// prints: (1,2) 1 \\ (2.5,3] 3 \\ (3,5) 2
// desired: (1,2) 1 \\ (2.5,5] 3 // value 2 gone
}
Run Code Online (Sandbox Code Playgroud)
编辑2: 基于@JorgeBellon的答案的完整解决方案:
#include<boost/icl/interval_map.hpp>
#include<iostream>
namespace icl = boost::icl;
template <class Type>
struct inplace_replace{// : icl::identity_based_inplace_combine<Type>{
using first_argument_type = Type;
void operator()(Type& object, Type const& operand) const{object = operand;}
};
using interval = icl::interval<double>;
int main(){
icl::interval_map<
double, int,
icl::partial_enricher, // Unmapped intervals have unkown value;
// store identity values
std::less , // Comparator
inplace_replace //, // Combination operator // IMPORTANT!!
// icl::inplace_erasure//, // Extraction operator
// closed_interval<unsigned, std::less> // Interval type
> joined_map;
joined_map.add({interval::open(1. , 2.), 1}); // or joined_map+=std::make_pair(...)
joined_map.add({interval::open(3. , 5.), 2}); // IMPORTANT: USE add, NOT insert!!
joined_map.add({interval::open(2.5, 5.), 3});
// ^^^^ this line now replaces the old value 2
for(auto e: joined_map) std::cout << e.first <<' '<< e.second <<'\n';
// prints: (1,2) 1 \\ (2.5,5] 3 // value 2 gone
}
Run Code Online (Sandbox Code Playgroud)
您可以在插入之前简单地擦除打算覆盖的部分的内容:
看到它住在Coliru:
#include <iostream>
#include <boost/icl/interval_map.hpp>
namespace icl = boost::icl;
int main()
{
icl::interval_map<double, int> joined_map;
using ival = icl::interval<double>;
joined_map.add({ival::open(1., 2.), 1});
joined_map.add({ival::open(3., 5.), 2});
std::cout << "#1: "; for(auto el : joined_map) std::cout << el.first << ": " << el.second << ", "; std::cout << "\n";
joined_map.erase(ival::open(3., 6.));
joined_map.add({ival::open(3., 6.), 4});
std::cout << "#2: "; for(auto el : joined_map) std::cout << el.first << ": " << el.second << ", "; std::cout << "\n";
}
Run Code Online (Sandbox Code Playgroud)
打印:
#1: (1,2): 1, (3,5): 2,
#2: (1,2): 1, (3,6): 4,
Run Code Online (Sandbox Code Playgroud)
我相信这就是您想要的。
旧答案文本,以供漫画浮雕将来参考
我感觉到interval_map的语义不是您所期望的。我现在已经玩了一点,不能说我理解它,但是我知道足以看到没有简单的1:1映射,其中插入的事物和存储在容器中的“元素”。
因此,与std :: map出现许多令人惊讶的差异
operator[]
,但operator[]
已超载(返回const
)find()
返回一个const_iterator
(大概是因为它可以返回以某种方式从实际数据派生的“虚拟节点”)。因此,您不能只是期望map.erase(find(k))
-您必须按键或间隔明确删除。add
和subtract
方法insert
。演示代码:
#include <iostream>
#include <boost/icl/interval_map.hpp>
#include <boost/icl/interval.hpp>
namespace icl = boost::icl;
int main()
{
icl::interval_map<double, int,
icl::partial_absorber,
/*ICL_COMPARE Compare =*/ ICL_COMPARE_INSTANCE(ICL_COMPARE_DEFAULT, double),
/*ICL_COMBINE Combine =*/ ICL_COMBINE_INSTANCE(icl::inplace_plus, int),
/*ICL_SECTION Section =*/ ICL_SECTION_INSTANCE(icl::inter_section, int)
> joined_map;
using ival = icl::interval<double>;
joined_map.add({ival::open(1., 2.), 1});
joined_map.add({ival::open(3., 5.), 2});
std::cout << "#1: "; for (auto el : joined_map) std::cout << el.first << ": " << el.second << ", "; std::cout << "\n";
auto clone1 = joined_map;
joined_map.add({3., 2});
std::cout << "#2: "; for (auto el : joined_map) std::cout << el.first << ": " << el.second << ", "; std::cout << "\n";
auto clone2 = joined_map;
joined_map.add({3., 2});
std::cout << "#3: "; for (auto el : joined_map) std::cout << el.first << ": " << el.second << ", "; std::cout << "\n";
auto clone3 = joined_map;
joined_map.add({ival::open(0., 6.), 10});
std::cout << "#4: "; for (auto el : joined_map) std::cout << el.first << ": " << el.second << ", "; std::cout << "\n";
auto clone4 = joined_map;
for (double x = 0; x < 7; x += .5)
{
std::cout << x
<< "\t" << clone1(x)
<< "\t" << clone2(x)
<< "\t" << clone3(x)
<< "\t" << clone4(x)
<< "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
看到它在Coliru上直播,打印:
#1: (1,2): 1, (3,5): 2,
#2: (1,2): 1, [3,5): 2,
#3: (1,2): 1, [3,3]: 4, (3,5): 2,
#4: (0,1]: 10, (1,2): 11, [2,3): 10, [3,3]: 14, (3,5): 12, [5,6): 10,
0 0 0 0 0
0.5 0 0 0 10
1 0 0 0 10
1.5 1 1 1 11
2 0 0 0 10
2.5 0 0 0 10
3 0 2 4 14
3.5 2 2 2 12
4 2 2 2 12
4.5 2 2 2 12
5 0 0 0 10
5.5 0 0 0 10
6 0 0 0 0
6.5 0 0 0 0
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助
归档时间: |
|
查看次数: |
1174 次 |
最近记录: |