我正在做一个接收映射的函数(映射包含字符串作为键,int作为值),如果发现值重复则抛出异常。我的第一次尝试是这样的:
typedef std::map<std::string, int>::iterator mapIt;
void mapcheck(std::map<std::string, int> &saidMap){
for (mapIt it = saidMap.begin(); it != saidMap.end(); it++){
try{
for (mapIt at = saidMap.begin(); at != saidMap.end(); at++){
if (at == it)
throw Myexception();
}
}
catch (Myexception &e){
std::cout << e.what() << std::endl;
}
}
}
但很明显,这只会在每次运行时抛出异常。是否有map的功能允许比较内部的值
答案 0 :(得分:2)
根据标准§23.4.4.1: A map
是一个关联容器,支持唯一键(每个键值最多包含一个)。
此外,在if
语句中,您将at
与it
进行比较,它们是迭代器,并且几乎总能保证它们不相等。因此,循环永远不会进入throw
。
如果您想要使用多个密钥进行映射,请使用multimap
。
如果您想比较map
的映射值,则应将if
条件更改为以下值:
if (at->second == it->second)
throw Myexception();
答案 1 :(得分:1)
这是您编写的代码的替代方法。如果您不受内存限制,另一种解决方案是使用std::set<int>
作为“测试容器”。std::set::insert()
函数可用于测试值而不是手动滚动内部循环。
typedef std::map<std::string, int>::iterator mapIt;
void mapcheck(std::map<std::string, int> &saidMap)
{
std::set<int> testSet;
for (mapIt it = saidMap.begin(); it != saidMap.end(); ++it)
{
try
{
if ( !testSet.insert(it->second).second )
throw Myexception();
}
catch (Myexception &e)
{
std::cout << e.what() << std::endl;
}
}
}
std::set::insert
函数尝试在集合中插入值,如果不成功,则返回std::pair
,其中“{second”值为false
。
与双嵌套循环相比,此解决方案的优点是set
的查找时间是对数的。
因此,例如,如果集合中已有100,000个整数,则最多需要16个比较来确定值是否在集合中。使用双嵌套for循环,您最多可以比较100,000个值。