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

Why isn't this code finding the length of the longest string in my set?

本文关键字:字符串 集合 段代码 代码 找不到 为什么      更新时间:2023-10-16

我在C++遇到了一个非常奇怪的集合迭代器问题。

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() 的值。

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

多谢!

我认为

这里的问题是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();
}

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

  • 将后递增++切换到前递增++以提高效率,
  • 使用->而不是(*).
  • 在运算符周围添加空格,以及
  • 在循环中本地声明迭代器

如下所示:

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

希望这有帮助!