代码之家  ›  专栏  ›  技术社区  ›  papirosnik

为什么按长度对字符串进行排序会得到不正确的结果?

  •  -2
  • papirosnik  · 技术社区  · 5 月前

    我想先按长度对字符串向量进行排序,然后按字母顺序排序。 我的快速初步实施:

    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    int main() {
    
        vector<string> words {"zzz", "aaazzz", "zz", "a"};
    
        sort(words.begin(), words.end(), [](auto& w1, auto& w2) {
            if (w1.length() < w2.length()) {
                return true;
            }
            return w1 < w2;
        });
    
        for (auto& w : words) {
            cout << w << endl;
        }
    
        return 0;
    }
    

    突然给了我错误的结果:

    a
    zz
    aaazzz
    zzz
    

    当我像这样改变lambda条件时:

    sort(words.begin(), words.end(), [](auto& w1, auto& w2) {
        if (w1.length() == w2.length()) {
            return w1 < w2;
        }
        return w1.length() < w2.length();
    });
    

    结果正常:

    a
    zz
    zzz
    aaazzz
    

    无法弄清楚我最初的状况有什么问题。为什么当其中的第一条语句非常明确地imho时,它没有产生预期的结果:

        if (w1.length() < w2.length()) {
            return true;
        }
    

    UPD:

    • 已将屏幕截图替换为文本
    • 谢谢大家,我明白了
    1 回复  |  直到 5 月前
        1
  •  2
  •   selbie    5 月前

    我很确定这一点:

        if (w1.length() < w2.length()) {
            return true;
        }
        return w1 < w2;
    

    应该是:

        if (w1.length() < w2.length()) {
            return true;
        }
        if (w1.length() > w2.length()) {
            return false;
        }
        return w1 < w2;
    

    你只想 w1 < w2 当两根绳子的长度不匹配时,应用“断领带器”。

    您可以优化掉对以下对象的冗余呼叫 length() ,但我打赌编译器无论如何都会在发布版本中这样做。但如果你只想有更短的代码:

        auto len1 = w1.length();
        auto len2 = w2.length();
        return (len1 != len2) ? (len1 < len2) : (w1 < w2);