sort自定义cmp

好的,我们来详细探讨一下在 C++ 中如何自定义 sort 的排序规则。

sort 函数是 C++ 标准库中的一个强大工具,它默认使用升序排列。但很多时候,我们需要根据特定的需求来排序,比如降序、按字符串长度、或者像你之前看到的那样,按自定义的拼接规则排序。

自定义 sort 排序规则的核心是提供一个比较函数(或函数对象),告诉 sort 函数两个元素 ab 应该如何比较,即 a 应该排在 b 的前面还是后面。

方法一:使用函数指针(最常用)

这是最直接、最常用的方法。我们定义一个普通的函数,然后将它的名字作为参数传递给 sort

1. 降序排序

这是一个简单的例子,展示如何对一个整数数组进行降序排序。

#include <iostream>
#include <vector>
#include <algorithm>

// 自定义比较函数
// 如果 a 应该排在 b 前面,返回 true
bool compareDescending(int a, int b) {
    return a > b; // 降序:大的数在前
}

int main() {
    std::vector<int> nums = {3, 1, 4, 1, 5, 9};
    
    // sort 的第三个参数就是我们的比较函数
    std::sort(nums.begin(), nums.end(), compareDescending);
    
    for (int num : nums) {
        std::cout << num << " ";
    }
    // 输出: 9 5 4 3 1 1
    return 0;
}

2. 按字符串长度排序

我们可以排序一个字符串 vector,让短的字符串排在前面。

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

// 比较两个字符串的长度
bool compareByLength(const std::string &a, const std::string &b) {
    return a.size() < b.size(); // 短的在前
}

int main() {
    std::vector<std::string> words = {"apple", "banana", "cherry", "date"};
    
    std::sort(words.begin(), words.end(), compareByLength);
    
    for (const std::string &word : words) {
        std::cout << word << " ";
    }
    // 输出: date apple banana cherry
    return 0;
}

方法二:使用 Lambda 表达式(C++11 及以后)

对于简单的比较逻辑,使用 Lambda 表达式可以让代码更简洁,因为你不需要在别处定义一个单独的函数。Lambda 表达式是一种匿名函数。

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> nums = {3, 1, 4, 1, 5, 9};
    
    // 使用 Lambda 表达式作为比较函数
    std::sort(nums.begin(), nums.end(), [](int a, int b) {
        return a > b; // 同样是降序排序
    });
    
    for (int num : nums) {
        std::cout << num << " ";
    }
    // 输出: 9 5 4 3 1 1
    return 0;
}

这对于一次性的、简单的比较逻辑非常方便。

方法三:使用函数对象(Functor)

函数对象是一个重载了 () 运算符的类。当你需要在比较函数中携带一些额外的状态(参数)时,这是一个非常强大的方法。

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

// 定义一个函数对象类
class StringComparator {
public:
    // 构造函数,用于接收额外的参数
    explicit StringComparator(bool ascending) : ascendingOrder(ascending) {}
    
    // 重载 () 运算符
    bool operator()(const std::string &a, const std::string &b) const {
        if (ascendingOrder) {
            return a.size() < b.size(); // 升序
        } else {
            return a.size() > b.size(); // 降序
        }
    }

private:
    bool ascendingOrder; // 用于存储排序方向的状态
};

int main() {
    std::vector<std::string> words = {"apple", "banana", "cherry", "date"};
    
    // 按长度降序排序
    StringComparator descComparator(false);
    std::sort(words.begin(), words.end(), descComparator);
    
    std::cout << "降序: ";
    for (const std::string &word : words) {
        std::cout << word << " ";
    }
    // 输出: 降序: banana cherry apple date
    
    std::cout << std::endl;
    
    // 按长度升序排序
    StringComparator ascComparator(true);
    std::sort(words.begin(), words.end(), ascComparator);
    
    std::cout << "升序: ";
    for (const std::string &word : words) {
        std::cout << word << " ";
    }
    // 输出: 升序: date apple banana cherry
    
    return 0;
}

总结与核心原则

无论使用哪种方法,你的比较函数都必须遵循一个基本原则,以确保 sort 能正确工作:

比较函数必须定义一个“严格弱序”(Strict Weak Ordering)。

简单来说,对于任意两个元素 ab

  1. 不可反身性compare(a, a) 必须返回 false。一个元素不能比它自己小。
  2. 不对称性:如果 compare(a, b)true,那么 compare(b, a) 必须为 false
  3. 传递性:如果 compare(a, b)truecompare(b, c)true,那么 compare(a, c) 必须为 true

在你之前提供的代码中,return (a+b)>(b+a); 这个比较函数就很好地遵守了这些规则,因此 sort 能够正确地对字符串进行排序,以得到最大的拼接结果。

// 你的比较函数
bool cmp(string a,string b){
	return (a+b)>(b+a); // "3"+"30" = "330" > "303" = "30"+"3"
}

总而言之,自定义 sort 的排序规则就是:创建一个比较函数,它接受两个同类型的参数 ab,并返回一个 bool 值,这个值为 true 就意味着 a 应该在排序后的序列中位于 b 之前。 你可以根据需要选择使用普通函数、Lambda 表达式或函数对象来实现这个比较逻辑。

posted @ 2025-11-19 14:26  EcSilvia  阅读(39)  评论(0)    收藏  举报