在地图中检查两个相同的值

时间:2014-05-18 01:19:30

标签: c++ map

我正在做一个接收映射的函数(映射包含字符串作为键,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的功能允许比较内部的值

2 个答案:

答案 0 :(得分:2)

根据标准§23.4.4.1: A map是一个关联容器,支持唯一键(每个键值最多包含一个)。

此外,在if语句中,您将atit进行比较,它们是迭代器,并且几乎总能保证它们不相等。因此,循环永远不会进入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个值。