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

时间:2013-10-22 02:23:40

标签: 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();
}

此代码帮助我将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();
}

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

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

非常感谢!

1 个答案:

答案 0 :(得分:6)

我认为这里的问题是string::length函数返回未签名类型,而您使用的int类型已签名。在有符号值和无符号值之间进行比较时,有符号值始终首先转换为无符号值。在您的情况下,将INT_MIN转换为无符号值会使其采用最大可能无符号值,因为INT_MINUINT_MAX的位模式相同。

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

要解决此问题,请在:

中添加一个强制转换
for (itr=dict.begin(); itr!=dict.end(); itr++) {
    if ( int((*itr).length()) > maxLen )
        maxLen = (*itr).length();
}

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

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

此处显示:

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

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

for (const auto& val: dict) {
    if (int(val.length()) > maxLen) {
       maxLen = val.length();
    }
}

希望这有帮助!