C++ sort自定义比较函数

这篇文章将讨论如何在 C++ 中对自定义对象的Vector进行排序。

STL 库提供 std::sort 中定义的算法 <algorithm> header,可用于对任何类型的对象进行排序。有很多方法可以做到:

1. 过载 T::operator<(T) 功能

推荐的方法是重载 operator< 对于对象类。这作为 operator< 是使用的默认顺序 std::sort 功能 (std::sort 它调用 std::less<> 这会将调用委托给 operator<).

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

#include <iostream>

#include <utility>

#include <vector>

#include <algorithm>

structNode

{

    std::stringfirst_name;

    std::string last_name;

    // 构造函数

    Node(std::string x,std::stringy): first_name(x),last_name(y){}

    // 重载 `operator<`

    booloperator<(const Node&r)const

    {

        if(first_name!=r.first_name){

            returnfirst_name<r.first_name;

        }

        returnlast_name< r.last_name;

    }

    // 重载操作符>(如果需要)

    booloperator>(constNode&r)const

    {

        if(first_name!= r.first_name){

            return first_name>r.first_name;

        }

        returnlast_name>r.last_name;

    }

};

intmain()

{

    std::vector<Node>v={

        {"Barack","Obama"},{"George", "Washington"},{"George","Bush"},

        {"Abraham","Lincoln"},{"John", "Tyler"},{"John","Kennedy"}

    };

    // 按名字的升序对Vector进行排序

    std::sort(v.begin(), v.end());

    // 按名字的降序对Vector进行排序

    // std::sort(v.begin(), v.end(), std::greater<Node>());

    for(constNode&node: v)

    {

        std::cout<<'{'<<node.first_name<<',' <<node.last_name<<'}';

        std::cout<<std::endl;

    }

    return0;

}

下载  运行代码

输出:

{Abraham,Lincoln}
{Barack,Obama}
{George,Bush}
{George,Washington}
{John,Kennedy}
{John,Tyler}

2. 过载 operator<(T, T) 功能

而不是定义 operator< (或者 operator>) 作为类的成员函数,我们也可以将它们用作自由运算符,如下所示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

#include <iostream>

#include <utility>

#include <vector>

#include <algorithm>

structNode

{

    std::stringfirst_name;

    std::string last_name;

    // 构造函数

    Node(std::string x,std::stringy): first_name(x),last_name(y){}

};

// 重载 `operator<`

booloperator<(constNode &x,constNode&y){

    if(x.first_name!= y.first_name){

        return x.first_name<y.first_name;

    }

    returnx.last_name<y.last_name;

}

intmain()

{

    std::vector<Node>v={

        {"Barack","Obama"},{"George", "Washington"},{"George","Bush"},

        {"Abraham","Lincoln"},{"John", "Tyler"},{"John","Kennedy"}

    };

    std::sort(v.begin(), v.end());

    for (constNode&node:v)

    {

        std::cout<<'{'<< node.first_name<<','<< node.last_name<<'}';

        std::cout<<std::endl;

    }

    return0;

}

下载  运行代码

输出:

{Abraham,Lincoln}
{Barack,Obama}
{George,Bush}
{George,Washington}
{John,Kennedy}
{John,Tyler}

3.自定义比较器

我们还可以编写自己的比较器并将其传递给 std::sort 功能。比较器函数决定在排序过程中如何对一个对象相对于另一个对象进行排序。比较器函数的编写和传递方式有很多种:

1. C++11 – 将 Lambda 作为比较参数传递给 sort()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

#include <iostream>

#include <utility>

#include <vector>

#include <algorithm>

structNode

{

    std::stringfirst_name;

    std::string last_name;

    // 构造函数

    Node(std::string x,std::stringy): first_name(x),last_name(y){}

};

intmain()

{

    std::vector<Node>v={

        {"Barack","Obama"},{"George", "Washington"},{"George","Bush"},

        {"Abraham","Lincoln"},{"John", "Tyler"},{"John","Kennedy"}

    };

    std::sort(v.begin(), v.end(),

            [](constNode&x,const Node&y){

                // 先比较姓氏

                if(x.last_name!= y.last_name){

                    return x.last_name<y.last_name;

                }

                // 仅当姓氏相等时才比较名字

                return x.first_name<y.first_name;

            });

    for(constNode&node:v)

    {

        std::cout <<'{'<<node.first_name<< ','<<node.last_name<<'}';

        std::cout<<std::endl;

    }

    return0;

}

下载  运行代码

输出:

{George,Bush}
{John,Kennedy}
{Abraham,Lincoln}
{Barack,Obama}
{John,Tyler}
{George,Washington}

2. 过载 bool operator()(T, T) 对于自定义类型

这里的想法是传递一个实现类的对象 () 运营商 sort() 作为比较函数。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

#include <iostream>

#include <utility>

#include <vector>

#include <algorithm>

structNode

{

    std::stringfirst_name;

    std::string last_name;

    // 构造函数

    Node(std::string x,std::stringy): first_name(x),last_name(y){}

};

structcomp

{

    bool operator()(constNode&x,const Node&y)const{

        // 先比较姓氏

        if(x.last_name!= y.last_name){

            return x.last_name<y.last_name;

        }

        // 仅当姓氏相等时才比较名字

        returnx.first_name <y.first_name;

    }

};

int main()

{

    std::vector<Node> v={

        {"Barack", "Obama"},{"George","Washington"}, {"George","Bush"},

        {"Abraham","Lincoln"},{"John", "Tyler"},{"John","Kennedy"}

    };

    std::sort(v.begin(), v.end(),comp());

    for(constNode&node:v)

    {

        std::cout<<'{'<<node.first_name<<','<< node.last_name<<'}';

        std::cout<<std::endl;

    }

    return0;

}

下载  运行代码

输出:

{George,Bush}
{John,Kennedy}
{Abraham,Lincoln}
{Barack,Obama}
{John,Tyler}
{George,Washington}

3.使用二进制函数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

#include <iostream>

#include <utility>

#include <vector>

#include <algorithm>

structNode

{

    std::stringfirst_name;

    std::string last_name;

    // 构造函数

    Node(std::string x,std::stringy): first_name(x),last_name(y){}

};

boolfn(constNode&x, constNode&y)

{

    // 先比较姓氏

    if(x.last_name!= y.last_name){

        return x.last_name<y.last_name;

    }

    // 仅当姓氏相等时才比较名字

    returnx.first_name< y.first_name;

}

intmain()

{

    std::vector<Node>v={

        {"Barack","Obama"},{"George", "Washington"},{"George","Bush"},

        {"Abraham","Lincoln"},{"John", "Tyler"},{"John","Kennedy"}

    };

    std::sort(v.begin(), v.end(),fn);

    for(constNode&node:v)

    {

        std::cout<<'{'<<node.first_name<<','<< node.last_name<<'}';

        std::cout<<std::endl;

    }

    return0;

}

下载  运行代码

输出:

{George,Bush}
{John,Kennedy}
{Abraham,Lincoln}
{Barack,Obama}
{John,Tyler}
{George,Washington}

这就是在 C++ 中对自定义对象的Vector进行排序。


谢谢阅读。

请使用我们的 在线编译器 使用 C、C++、Java、Python、JavaScript、C#、PHP 和许多更流行的编程语言在评论中发布代码。

像我们?将我们推荐给您的朋友,帮助我们成长。快乐编码 🙂