目录
1.为什么要引入运算符重载
2.运算符重载写法
格式
例子
示例代码
运行结果
3.sort函数
两种声明
声明1:默认情况
参数
示例代码1:排整型
示例代码2:排浮点数
编辑
示例代码3:排字符串
声明2:自定义情况
参数
comp比较函数的两种写法
写法1:创建比较函数
示例代码4:排降序
写法2:结构体中重载()运算符-仿函数
示例代码5:排降序
4.对比C语言的strcmp和C++的sort函数在按字典序为结构体排序
1.C语言代码
2.C++代码
1.为什么要引入运算符重载
#include <iostream>
using namespace std;
struct s
{
int i;
char c;
float f;
s()
{
i = 1;
c = 'c';
f = 3.14;
}
};
int main()
{
s s1;
cout << s1.i << s1.c << s1.f << endl;
return 0;
}
cout语句写的有点麻烦,能不能直接使用cout<<s1<<endl来进行打印呢?
在VS上编译会报错
解决这个问题,需要运算符重载,即在C++中要针对自定义类型的变量,使用 cout 和 << 来输出变量的内容,就要对<<这个输出运算符进行重载
2.运算符重载写法
格式
返回类型 operator需要重载的运算符(参数列表)
{
函数体;
}
例子
如果是cout的<<运算符重载,则返回类型为ostream&
ostream& operator<<(ostream&os,s& s1)
{
os << s1.i << s1.c << s1.f << endl;
return os;
}
示例代码
#include <iostream>
using namespace std;
struct s
{
int i;
char c;
float f;
s()
{
i = 1;
c = 'c';
f = 3.14;
}
};
ostream& operator<<(ostream&os,s& s1)
{
os << s1.i << s1.c << s1.f << endl;
return os;
}
int main()
{
s s1;
cout<<s1<<endl;
return 0;
}
运行结果
3.sort函数
使用前要包含<algorithm>头文件
两种声明
声明1:默认情况
//default (1)
template <class RandomAccessIterator>
void sort (RandomAccessIterator first, RandomAccessIterator last);
备注:有关template和class方面的知识这里不做介绍,在竞赛中只需要明白参数的含义以及如何调用即可
参数
first:指向要排序范围的第一个元素的迭代器或者指针
last:指向要排序范围的最后一个元素之后位置的迭代器或者指针
声明1为sort函数的默认情况,默认排升序
示例代码1:排整型
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int arr[]={1,5,2,5,7,43,2,7,0,6};
sort(arr,arr+sizeof(arr)/sizeof(arr[0]));
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
cout<<arr[i]<<" ";
return 0;
}
运行结果
示例代码2:排浮点数
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
float arr[]={1.4,5.23,2.56,5.55,7.14};
sort(arr,arr+sizeof(arr)/sizeof(arr[0]));
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
cout<<arr[i]<<" ";
return 0;
}
运行结果
示例代码3:排字符串
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
string s="ajisfdhvajiw";
sort(s.begin(),s.end());
cout<<s;
return 0;
}
注:s.end()返回指向字符串最后一个字符的下一个位置的迭代器(在C13.【C++ Cont】初识string类字符串的迭代器文章讲过),因此不用写成sort(s.begin(),s.end()+1);
运行结果
声明2:自定义情况
由于默认情况只能排升序,但可以自定义排降序或者排其他类型的数据(例如结构体)
//custom (2)
template <class RandomAccessIterator, class Compare>
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
参数
first和last参数同默认情况说明的
comp为自定义比较函数或函数对象,用于指定排序方法(默认情况下没有这个参数,这是自定义情况和默认情况不同的地方),可以类比之前在119.【C语言】数据结构之快速排序(调用库函数)文章讲过的qsort函数
注意:comp必须返回类型为bool型,如果第一个参数应该排在第二个参数之前,则返
回 true(不会交换),否则返回false(会交换)
comp比较函数的两种写法
写法1:创建比较函数
示例代码4:排降序
#include <iostream>
#include <algorithm>
using namespace std;
bool comp(int a,int b)
{
return a>b;
}
int main()
{
int arr[]={1,5,2,5,7,43,2,7,0,6};
sort(arr,arr+sizeof(arr)/sizeof(arr[0]),comp);
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
cout<<arr[i]<<" ";
return 0;
}
解释return a>b;
a>b如果为真,则不需要交换a和b,顺序是正确的(return true)
a>b如果为假,即a<b,则需要交换a和b,顺序是错误的(return false),交换后变为a>b,即排降序
运行结果
写法2:结构体中重载()运算符-仿函数
仿函数也叫函数对象,竞赛中不需要了解原理,只需要会用即可
示例代码5:排降序
#include <iostream>
#include <algorithm>
using namespace std;
struct cmp
{
bool operator()(int a,int b)//()运算符重载
{
return a>b;
}
}comp;
int main()
{
int arr[]={1,5,2,5,7,43,2,7,0,6};
//将结构体对象作为第三个参数传入sort函数中
sort(arr,arr+sizeof(arr)/sizeof(arr[0]),comp);
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
cout<<arr[i]<<" ";
return 0;
}
运行结果
4.对比C语言的strcmp和C++的sort函数在按字典序为结构体排序
1.C语言代码
给定下列结构体,要求对姓名按字典序升序输出
struct Stu
{
char name[10];
short score;
};
struct Stu s[] = {
{"zhang",95},
{"wang",74},
{"li",83},
{"sun",90},
{"qian",66}
};
main代码
#include <stdio.h>
#include <string.h>
int main()
{
int sz = sizeof(s) / sizeof(s[0]);
for (int i = 0; i < sz; i++)
{
for (int j = i + 1; j < sz; j++)
{
if (strcmp(s[i].name, s[j].name)<0)
{
struct Stu tmp = s[i];//结构体可以直接赋值
s[i] = s[j];
s[j] = tmp;
}
}
}
for (int k = 0; k < sz; k++)
{
printf("%s,%d\n", s[k].name, s[k].score);
}
return 0;
}
运行结果
2.C++代码
给定下列结构体,要求对姓名按字典序升序输出
struct Stu
{
string name;
short score;
};
struct Stu s[] = {
{"zhang",95},
{"wang",74},
{"li",83},
{"sun",90},
{"qian",66}
};
main代码
#include <iostream>
#include <algorithm>
//不用传struct Stu&,comp_by_name只是提供一个比较规则,实际在排序是还是取决于sort
bool comp_by_name(struct Stu a, struct Stu b)
{
return a.name < b.name;
}
int main()
{
int sz = sizeof(s) / sizeof(s[0]);
sort(&s[0], &s[sz], comp_by_name);
for (int k = 0; k < sz; k++)
{
cout << s[k].name << " " << s[k].score << endl;
}
}
注:comp_by_name也可以写成仿函数的形式
struct cmp
{
bool operator()(struct Stu a, struct Stu b)
{
return a.name < b.name;
}
}comp_by_name;
int main()
{
int sz = sizeof(s) / sizeof(s[0]);
sort(&s[0], &s[sz], comp_by_name);
for (int k = 0; k < sz; k++)
{
cout << s[k].name << " " << s[k].score << endl;
}
}
运行结果
与C++代码对比,C语言代码可以看到比较麻烦,而C++代码非常简洁