将迭代器设置为具有最高键的值
set iterator to value with highest key
我有一个带有分数的字符串集合,我想找到分数最高的字符串。现在,由于 std::map
将其项目按键排序,我认为这将是一个完美的存储 class。现在我在将迭代器指向最后一项时遇到了问题(以检索得分最高的值)。我得到的是:
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
为什么我没有得到预期的结果?
end()
为您提供了一个超过容器末尾的迭代器。这意味着只要地图不为空,最后一个有效的迭代器就是 end() - 1
。将代码更改为
it = std::prev(m.end());
将为您提供地图中的最后一个元素。
CONTAINER::end()
不指向容器中的最后一个元素,而是指向最后一个元素 之后 的元素 - 标记值。这就是为什么你的输出是一些垃圾值;你只是在随机搜索一段内存
Returns an iterator to the element following the last element of the container.
This element acts as a placeholder; attempting to access it results in undefined behavior.
或者,使用 std::map::rbegin() 迭代器。它指向非反转映射的最后一个元素:
auto it = m.rbegin();
或:
auto it = std::rbegin(m);
如果您有可用的提升,我们可以很好地检查空地图并采取适当的措施:
#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 不支持可选引用。
我有一个带有分数的字符串集合,我想找到分数最高的字符串。现在,由于 std::map
将其项目按键排序,我认为这将是一个完美的存储 class。现在我在将迭代器指向最后一项时遇到了问题(以检索得分最高的值)。我得到的是:
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
为什么我没有得到预期的结果?
end()
为您提供了一个超过容器末尾的迭代器。这意味着只要地图不为空,最后一个有效的迭代器就是 end() - 1
。将代码更改为
it = std::prev(m.end());
将为您提供地图中的最后一个元素。
CONTAINER::end()
不指向容器中的最后一个元素,而是指向最后一个元素 之后 的元素 - 标记值。这就是为什么你的输出是一些垃圾值;你只是在随机搜索一段内存
Returns an iterator to the element following the last element of the container. This element acts as a placeholder; attempting to access it results in undefined behavior.
或者,使用 std::map::rbegin() 迭代器。它指向非反转映射的最后一个元素:
auto it = m.rbegin();
或:
auto it = std::rbegin(m);
如果您有可用的提升,我们可以很好地检查空地图并采取适当的措施:
#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 不支持可选引用。