增加迭代器标准映射

Increment an iterator standard map

本文关键字:映射 标准 迭代器 增加      更新时间:2023-10-16

ALL,

std::map<int, std::string> addressee;
std::map<int, std::string>::iterator it1, it2;
for( it1 = addressee.begin(); it1 != addressee().end(); it1++ )
{
    bool found = false;
    for( it2 = it1 + 1; it2 != addressee.end() && !found; it2++ )
    {
       if( it1->second == it1->second )
       {
           printf( "Multiple occurences of addressees found" );
           found = true;
       }
    }
}

gcc抛出一个错误:运算符+不匹配。

这段代码是我现在尝试做的事情的简化版本。我想我可以使用std::advanced(),但这似乎只是浪费函数调用。

有更好的解决办法吗?

std::map没有随机访问迭代器,只有双向迭代器。因此没有+ n操作。相反,使用std::next:

#include <iterator>
#include <map>
// ...
for (auto it1 = addressee.begin(), e = addressee.end(); it1 != e; ++it1)
{
    for (auto it2 = std::next(it1); it2 != e; ++it2)
    {
        if (it1->second == it2->second)
        {
            // ...
            break;
        }
    }
}

事实上,您应该始终使用std::next,因为它知道其参数的迭代器类别以及计算下一个迭代器的最有效方法。这样,您就不必关心碰巧使用的特定容器。

@Kerrek已经指出了如何在语法层面处理您遇到的问题。

我将从更算法的层面来考虑这个问题——你真正想完成的是什么,而不仅仅是看如何修复特定的代码行。

除非所涉及的集合是可靠的miny,所以此操作的效率根本无关紧要,否则我会从集合中复制映射的值,然后在其上使用sortunique来查看是否有重复:

std::vector<std::string> temp;
std::transform(addressee.begin(), addressee.end(), 
               std::back_inserter(temp),
               [](std::pair<int, std::string> const &in) { return in.second; });
std::sort(temp.begin(), temp.end());
if (std::unique(temp.begin(), temp.end()) != temp.end()) {
   std::cout << "Multiple occurrences of addressees found";
   found = true;
}

这将复杂性从O(N2)降低到O(N log N),如果集合很大,这通常是相当可观的。