增加迭代器标准映射
Increment an iterator standard map
全部,
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::advance(),但它似乎只会浪费函数调用。
有更好的解决方法吗?
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 已经指出了如何处理您在句法级别遇到的问题。
我将在更算法的层面上考虑这个问题——你真正想要整体完成的是什么,而不是仅仅着眼于如何修复特定的代码行。
除非所涉及的集合可靠 tiny 所以这个操作的效率根本不重要,我会从集合中复制映射值,然后使用 sort
和 unique
来查看是否有重复:
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),如果集合非常大,这通常会相当可观。
全部,
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::advance(),但它似乎只会浪费函数调用。
有更好的解决方法吗?
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 已经指出了如何处理您在句法级别遇到的问题。
我将在更算法的层面上考虑这个问题——你真正想要整体完成的是什么,而不是仅仅着眼于如何修复特定的代码行。
除非所涉及的集合可靠 tiny 所以这个操作的效率根本不重要,我会从集合中复制映射值,然后使用 sort
和 unique
来查看是否有重复:
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),如果集合非常大,这通常会相当可观。