为什么这段代码没有找到我集合中最长字符串的长度?

use*_*802 2 c++ iterator set

我在C++中遇到了一个非常奇怪的set迭代器问题.

set<string> dict;
dict.insert("hello");
dict.insert("my");

int maxLen = INT_MIN;

set<string>::iterator itr;
for (itr=dict.begin(); itr!=dict.end(); itr++) {
    int len = (*itr).length();
    if ( len > maxLen )
        maxLen = (*itr).length();
}
Run Code Online (Sandbox Code Playgroud)

这段代码帮助我将maxLen设置为5,这是单词集中最长单词的长度.

set<string> dict;
dict.insert("hello");
dict.insert("my");

int maxLen = INT_MIN;

set<string>::iterator itr;
for (itr=dict.begin(); itr!=dict.end(); itr++) {
    if ( (*itr).length() > maxLen )
        maxLen = (*itr).length();
}
Run Code Online (Sandbox Code Playgroud)

但是,这段代码无法给我正确的结果.运行代码后,maxLen仍然是INT_MIN的值.基本上没什么变化,除了我不再使用变量来保存(*itr).length()的值.

这对我来说很奇怪.我错过了什么吗?我只想澄清我对迭代器使用的怀疑.

非常感谢!

tem*_*def 6

我认为这里的问题是该string::length函数返回一个无符号类型,而int您正在使用的类型已签名.在有符号值和无符号值之间进行比较时,有符号值始终首先转换为无符号值.在你的情况下,转换INT_MIN到一个无符号的价值,所以采取了最大可能的无符号数,因为对位模式INT_MINUINT_MAX是相同的.

这是第一次使用的原因是无符号值int在分配给临时变量时被强制转换为s.

要解决此问题,请在以下位置添加强制转换:

for (itr=dict.begin(); itr!=dict.end(); itr++) {
    if ( int((*itr).length()) > maxLen )
        maxLen = (*itr).length();
}
Run Code Online (Sandbox Code Playgroud)

只要你在这里,你可以在这里做很多其他的风格修复,例如

  • 将后增量转换++为增量++效率,
  • 使用->代替(*).,
  • 在运算符周围添加空格,以及
  • 在循环中本地声明迭代器

这显示在这里:

for (set<string>::iterator itr = dict.begin(); itr != dict.end(); ++itr) {
    if (int(itr->length()) > maxLen) {
       maxLen = itr->length();
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您有一个符合C++ 11的编译器,则使用基于范围的for循环:

for (const auto& val: dict) {
    if (int(val.length()) > maxLen) {
       maxLen = val.length();
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!