使用最高键将迭代器设置为值

时间:2018-08-16 13:12:05

标签: c++ iterator stdmap

我有一个带有分数的字符串集合,我想找到分数最高的字符串。现在,由于std::map保持其键项的顺序,所以我认为这将是一个完美的存储类。现在,我遇到了将迭代器指向最后一项的问题(以检索得分最高的值)。我所拥有的是:

int main(void)
{

    map<double, string> m;

    m.insert(std::pair<double,string>(79.43567,"ARH1265"));
    m.insert(std::pair<double,string>(69.83569,"ZRE5265"));
    m.insert(std::pair<double,string>(73.03261,"TA9318"));
    m.insert(std::pair<double,string>(93.43567,"CRP5285"));

    cout << "size: " << m.size() << endl;

    map<double, string>::iterator it;

    for (it = m.begin(); it != m.end(); it++) {
        cout  << it->first << " : " << it->second << endl;
    }

    it = m.end();
    cout << "last element is: " << it->first << " : " << it->second << endl;

return 0;
}

给我输出:

size: 4
69.8357 : ZRE5265
73.0326 : TA9318
79.4357 : ARH1265
93.4357 : CRP5285
last element is: 1.97626e-323 : ARH1265

我期望得到的时间:

size: 4
69.8357 : ZRE5265
73.0326 : TA9318
79.4357 : ARH1265
93.4357 : CRP5285
last element is: 93.4357 : CRP5285

为什么我没有得到期望?

5 个答案:

答案 0 :(得分:4)

或者,使用Arask迭代器。它指向非反向映射的最后一个元素:

auto it = m.rbegin();

或:

auto it = std::rbegin(m);

答案 1 :(得分:3)

end()为您提供了一个迭代器,该迭代器位于容器末尾。这意味着只要映射不为空,最后一个有效的迭代器为end() - 1。将代码更改为

it = std::prev(m.end());

将为您提供地图中的最后一个元素。

答案 2 :(得分:2)

CONTAINER::end()并不指向容器中的最后一个元素,而是最后一个元素之后的元素-一个前哨值。这就是为什么您的输出是一些垃圾值的原因;您只是在随机寻找内存

答案 3 :(得分:1)

来自std::map::end

  

将迭代器返回到容器最后一个元素之后的元素。   此元素充当占位符;尝试访问它会导致未定义的行为。

答案 4 :(得分:0)

如果您有增强功能,我们可以很好地检查是否有空地图并采取适当的措施:

#include <map>
#include <iostream>

#include <boost/optional.hpp>


template<class K, class V, class C, class A>
auto last_item(std::map<K, V, C, A> const& m) 
-> 
boost::optional<typename std::map<K, V, C, A>::value_type const&>
{
    boost::optional<typename std::map<K, V, C, A>::value_type const&> result;

    if (!m.empty())
    {
        result = *std::prev(std::end(m));
    }

    return result;
}

int main(void)
{

    std::map<double, std::string> m;

    m.insert(std::pair<double,std::string>(79.43567,"ARH1265"));
    m.insert(std::pair<double,std::string>(69.83569,"ZRE5265"));
    m.insert(std::pair<double,std::string>(73.03261,"TA9318"));
    m.insert(std::pair<double,std::string>(93.43567,"CRP5285"));

    std::cout << "size: " << m.size() << std::endl;

    std::map<double, std::string>::iterator it;

    for (it = m.begin(); it != m.end(); it++) {
        std::cout  << it->first << " : " << it->second << std::endl;
    }


    if (auto opt_last = last_item(m))
    {
        std::cout << "last element is: " << opt_last->first << " : " << opt_last->second << std::endl;
    }
    else
    {
        std::cout << "the map is empty\n";
    }

    return 0;
}

不幸的是,即使对于c ++ 17,我们也不能为此使用std::optional,因为std :: optional不支持可选引用。