【问题标题】:getting "index" of set element via iterator [duplicate]通过迭代器获取集合元素的“索引”[重复]
【发布时间】:2012-11-22 03:40:50
【问题描述】:

此问题适用于std::setstd::unsorted_set

我有一个指向集合中元素的迭代器。我想使用迭代器根据元素在集合中的位置获取元素的“索引”。

例如,我的集合的索引如下:

int index = 0;

for(MySetType::iterator begin = mySet.begin(); begin != mySet.end(); begin++)
{
    cout << "The index for this element is " << index;
    index++;
}

我尝试过使用迭代器进行算术运算,但它不起作用:

int index = mySetIterator - mySet.begin();

有没有办法使用迭代器根据它在集合中的位置来获取这样的索引值?

【问题讨论】:

  • 获得两个迭代器之间“距离”的正确方法是std::distance 函数。但是,请在使用前阅读答案杰克。

标签: c++ stl iterator


【解决方案1】:

使用STL distance,即std::distance(set.begin(), mySetIterator)

请注意:

返回第一个和最后一个之间的元素数。 行为 未定义 如果 last 不能从 first by 到达(可能 重复)首先递增。

备注:复杂度是线性的;

但是,如果 InputIt 额外满足 LegacyRandomAccessIterator,复杂度不变。

【讨论】:

    【解决方案2】:

    std::setset::unordered_setassociative 容器,而不是 sequence 容器,因此索引的概念本身没有多大意义。

    如果您需要检索关联容器的索引,则应更改设计(即使没有最少或最近插入元素的概念,此类容器中的索引也可能会更改)。

    【讨论】:

    • 我只需要一个“索引”来链接元素(迭代器)以可以写入文件的方式设置项目。换句话说,我有一个庞大的集合迭代器列表,我不想将相同的冗余集合元素数据写入文件。我宁愿将唯一的集合元素写入一个文件,然后为每个元素创建一个索引,将它们链接回特定的集合项。
    • 索引的概念很有意义,例如set&lt;ChessPlayer&gt; players; int RankOf(ChessPlayer player, const set&lt;ChessPlayer&gt;&amp; players); players.insert(newPlayer); players.erase(retiredPlayer) 现在你将如何实现一个高效的RankOf 函数?
    【解决方案3】:

    std::set has just a bidirectional iterator,这意味着你不能用operator +(或-)做你想做的事情。这些仅供random access iterators 使用,就像std::vector 提供的一样。

    您需要使用std::distance 来获取“索引”,并使用std::advance 从集合的开头移动到结尾。

    auto distance = std::distance(mySet.begin(), someIterator);
    auto it = mySet.begin();
    std::advance(it, distance);
    
    assert(it == someIterator);
    

    【讨论】:

    • 在set的情况下distance()函数的时间复杂度是多少?是 O(1) 吗?
    • 不,因为set 只有一个bidirectional iteratordistance 必须遍历列表。如果它有random access iterators,它可能是 O(1)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 2015-11-14
    相关资源
    最近更新 更多