C++ C++;:需要索引集

C++ C++;:需要索引集,c++,set,containers,indexed,C++,Set,Containers,Indexed,我需要一个索引关联容器,其操作如下: 最初为空,大小为0 当我向它添加一个新元素时,它会将它放置在索引[size],非常类似于向量的push_back。它增加大小并返回新添加元素的索引 如果元素已经存在,它将返回它出现的索引 Set似乎是实现这一点的理想数据结构,但我看不到任何类似于 查找操作中的索引。在集合上查找返回元素的迭代器 在这种情况下,使用set.begin()处理差异是正确的做法吗?STL中没有立即适合的数据结构,但实现这一点的一种简单且相当有效的方法是使用映射和指针向量。map

我需要一个索引关联容器,其操作如下:

  • 最初为空,大小为0

  • 当我向它添加一个新元素时,它会将它放置在索引[size],非常类似于向量的push_back。它增加大小并返回新添加元素的索引

  • 如果元素已经存在,它将返回它出现的索引

Set似乎是实现这一点的理想数据结构,但我看不到任何类似于 查找操作中的索引。在集合上查找返回元素的迭代器


在这种情况下,使用set.begin()处理差异是正确的做法吗?

STL中没有立即适合的数据结构,但实现这一点的一种简单且相当有效的方法是使用映射和指针向量。
map
将对象映射到它们在数组中的索引(这样检查对象是否存在是有效的,如果对象确实存在,索引立即就在手边),而
vector
将索引映射到映射中的对象(这样按索引检索对象是有效的)

就这样。一个问题当然是,一旦对象在集合中,就不能修改它。这是它在这里实现方式的一种泄漏,因为映射键是常量,原因很明显——但事实上,不管实现如何,它都是我们想要的。如果你坚持不复制,那么一旦一个对象在列表中,它就不能被修改,以防任何修改都会使它成为另一个对象的副本


(还请注意,我在这里使用
size\t
有点作弊--我想
std::vector::size\u type
可能更准确--这主要是为了简洁!)

STL中没有立即适合的数据结构,但实现这一点的一种简单且相当有效的方法是使用映射和指针向量。
map
将对象映射到它们在数组中的索引(这样检查对象是否存在是有效的,如果对象确实存在,索引立即就在手边),而
vector
将索引映射到映射中的对象(这样按索引检索对象是有效的)

就这样。一个问题当然是,一旦对象在集合中,就不能修改它。这是它在这里实现方式的一种泄漏,因为映射键是常量,原因很明显——但事实上,不管实现如何,它都是我们想要的。如果你坚持不复制,那么一旦一个对象在列表中,它就不能被修改,以防任何修改都会使它成为另一个对象的副本


(还请注意,我在这里使用
size\t
有点作弊--我想
std::vector::size\u type
可能更准确--这主要是为了简洁!)

如果从中间删除一个元素会怎么样。它背后的元素的索引应该改变还是不应该改变?@sbi的目的是什么,我认为:如果索引在删除后不应该改变,
std::map
会很好地工作。@Thomas:我也这么认为,直到我意识到他想检查值是否已经存在。这是一个
std::map
@sbi中的O(n):你几乎让我相信了一段时间。但是我们要将值映射到索引:
std::map
@Thomas:但是按索引进行查找将是O(n)。他正在寻找的可能是一个多索引容器。如果从中间删除一个元素会怎么样。它背后的元素的索引应该改变还是不应该改变?@sbi的目的是什么,我认为:如果索引在删除后不应该改变,
std::map
会很好地工作。@Thomas:我也这么认为,直到我意识到他想检查值是否已经存在。这是一个
std::map
@sbi中的O(n):你几乎让我相信了一段时间。但是我们要将值映射到索引:
std::map
@Thomas:但是按索引进行查找将是O(n)。他要找的可能是一个多索引容器。
std::map<T,size_t> objects;
std::vector<const T *> indexed;
size_t add_element(const T &v) {
    std::map<T,size_t>::iterator it=objects.find(v);
    if(it==objects.end()) {
        it=objects.insert(std::map<T,size_t>::value_type(v,objects.size())).first;
        indexed.push_back(&it->first);
    }
    return it->second;
}
const T &get_element(size_t index) {
    return *indexed[index];
}