例题:sort关于int的自定义规则的排序
-
sort
-
基本用法:sort(数组名+n1, 数组名+n2) 将下标范围为[n1, n2)从小到大
-
拓展用法1:sort(数组名+n1, 数组名+n2, greater()); 从大到小
-
拓展用法2:sort(数组名+n1, 数组名+n2,排序规则结构名());
-
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#include<set>struct Rule1{
bool operator()(const int & a1, const int & a2)const{
return a1>a2;
}
};
struct Rule2{
bool operator()(const int & a1, const int & a2)const{
return a1%10<a2%10;
}
};
void Print(int a[], int size){
for(int i = 0; i < size; ++i){
cout<<a[i]<<",";
}
cout<<endl;
}
int main(){
int a[] = {12,45,3,98,21,7};
int n = sizeof(a)/sizeof(int);
sort(a, n);
cout<<"1) ";Print(a, n);
sort(a, a+n, Rule1());
cout<<"2) ";Print(a, n);
sort(a, a+n, Rule2());
cout<<"3) ";Print(a, n);
return 0;
}
例题:sort关于结构体的自定义排序
以及二分查找binary_search的应用
-
binary_search
-
查找区间为下标范围[n1,n2)的元素
-
拓展用法:再加上排序规则结构名
-
查找时的排序规则,必须和排序时的规则一致
-
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#include<set>
struct Student{
char name[20];
char id[4];
double gpa;
};
Student students[]={{"Jack", "112", 3.4}, {"Mary", "102", 3.8}, {"Mary", "117", 3.9},{"Ala", "333", 3.5}, {"Zero", "101", 4.0}};
struct StudentRule1{
bool operator()(const Student & s1, const Student & s2)const{
if(stricmp(s1.name, s2.name)<0)
return true;
return false;
}
};
struct StudentRule2{
bool operator()(const Student & s1, const Student & s2)const{
if(stricmp(s1.id, s2.id)<0){
return true;
}
return false;
}
};
struct StudentRule3{
bool operator()(const Student & s1, const Student & s2)const{
return s1.gpa>s2.gpa;
}
};
void StudentsPrint(Student s[], int size){
for(int i = 0; i < size; ++i){
cout<<"("<<s[i].name<<","<<s[i].id<<","<<s[i].gpa<<")";
}
cout<<endl;
}
int main(void){
Student s;
strcpy(s.name, "Mary"); //这赋值方式可以借鉴
strcpy(s.id, "117"); //字符串如果不是在定义的时候初始化,之后就不能再将整个字符串赋值给这个字符数组了
s.gpa = 0;
int n = sizeof(students)/sizeof(Student);
sort(students, students+n, StudentRule1());
//自定义排序用什么排序二分查找就用什么查找(关键字),因为二分查找的原理
//举个例子就是:上面用名字来排序的,查找的时候就用名字来查找,也只根据名字弄
cout<<binary_search(students, students+n, s, StudentRule1())<<endl;
strcpy(s.name, "Bob");
cout<<binary_search(students, students+n, s, StudentRule1())<<endl;
sort(students, students+n, StudentRule2());
cout<<binary_search(students, students+n, s, StudentRule2())<<endl;
return 0;
}
lower_search和upper_search二分查找下界的应用举例
-
lower_search
-
T *lower_bound(数组+n1, 数组+n2, 值);
-
查找区间里下标最小的,大于等于“值”的元素,如果找不到则p指向下标为n2的元素
-
还可以按照自定义的排序规则,不过查找是应该按照排序时的规则来查找
-
-
upper_search
- 查找区间下标最小的,大于“值”的元素,如果找不到则p指向下标为n2的元素
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#include<set>
#define NUM 7
struct Rule{
bool operator()(const int & a1, const int & a2)const{
return a1%10<a2%10;
}
};
void Print(int a[], int size){
for(int i = 0; i < size; ++i){
cout<<a[i]<<",";
}
cout<<endl;
}
int main(void){
int a[NUM] = {12, 5, 3, 5, 98, 21, 7};
sort(a, a+NUM);
Print(a, NUM);
int *p = lower_bound(a, a+NUM, 4);
cout<<*p<<","<<p-a<<endl;
//lower_bound是查找区间下标最小的,大于等于值的元素,如果找不到,p指向下标为n2的元素
//upper_bound是查找区间下标最小的,大于值的元素,如果找不到就返回n2的下标
p = upper_bound(a, a+NUM, 5);
cout<<*p<<endl;
cout<<*upper_bound(a, a+NUM, 13)<<endl;
sort(a, a+NUM, Rule());
Print(a, NUM);
cout<<*lower_bound(a, a+NUM, 16, Rule())<<endl;
cout<<lower_bound(a, a+NUM, 25, Rule())-a<<endl;
cout<<upper_bound(a, a+NUM, 18, Rule())-a<<endl;
if(upper_bound(a, a+NUM, 18, Rule())==a+NUM)
cout<<"not found"<<endl;
cout<<*upper_bound(a, a+NUM, 5, Rule())<<endl;
cout<<*upper_bound(a, a+NUM, 4, Rule())<<endl;
return 0;
}
STL中的平衡二叉树
-
multiset变量st中可以存放T类型的数据,并能自动排序,开始st为空
-
st.insert 添加元素 st.find 查找元素 st.erase 删除元素
-
multiset::iterator p;
-
p是迭代器,相当于指针,访问multiset中的元素要通过迭代器
-
multiset上的迭代器可++, --, !=, == 但是不可以比较大小,不可以加减整数,不可相减
-
-
multiset st;
-
st.begin():指向头一个元素的迭代器
-
st.end():指向最后一个元素后面的迭代器
-
#include<iostream>
#include<cstring>
#include<algorithom>
#include<set>
int main(void){
multiset<int> st;
int a[10] = {1,14,12,13,7,13,21,19,8,8};
for(int i = 0; i < 10; ++i)
st.insert(a[i]);
multiset<int>::iterator i;
for(i = st.begin(); i != st.end(); ++i)
cout<<*i<<",";
cout<<endl;
i = st.find(22);
if(i==st.end())
cout<<"not found"<<endl;
st.insert(22);
i = st.find(22);
if(i == st.end())
cout<<"not found"<<endl;
else
cout<<"found:"<<*i<<endl;
i = st.lower_bound(13);
cout<<*i<<endl;
i = st.upper_bound(8);
cout<<*i<<endl;
st.erase(i);
for(i = st.begin(); i != st.end(); ++i)
cout<<*i<<",";
return 0;
}
#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
struct Rule1{
bool operator()(const int & a1, const int &a2)const{
return (a1%10)<(a2%10);
}
};
int main(void){
multiset<int, greater<int> >st;
int a[10] = {1,14,12,13,7,13,21,19,8,8};
for(int i = 0; i < 10; ++i)
st.insert(a[i]);
multiset<int, greater<int> >::iterator i;
for(i = st.begin(); i != st.end(); ++i)
cout<<*i<<",";
cout<<endl;
multiset<int, Rule1 > st2;
for(int i = 0; i < 10; ++i)
st2.insert(a[i]);
multiset<int, Rule1 >::iterator p;
for(p = st2.begin(); p!=st2.end(); ++p)
cout<<*p<<",";
cout<<endl;
p = st2.find(133);
cout<<*p<<endl;
return 0;
}
自定义排序规则的multiset用法
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#include<set>
struct Student{
char name[20];
int id;
int score;
};
Student students[] = {{"Jack", 112, 78}, {"Mary", 102, 85},
{"Ala", 333, 92}, {"Zero", 101, 70}, {"Cindy", 102, 78}};
student Rule{
bool operator()(const Student & s1, const Student & s2)const{
if(s1.score != s2.score)
return s1.score>s2.score;
else
return (strcmp(s1.name, s2.name)<0);
}
};
int main(){
multiset<Student, Rule> st;
for(int i = 0; i < 5; ++i)
st.insert(students[i]);
multiset<Student, Rule>::iterator p;
for(p = st.begin(); p != st.end(); ++p)
cout<<p->score<<" "<<p->name<<" "<<p->id<<endl;
Student s = {"Mary", 1000, 85};
p = st.find(s);
if(p != st.end());
cout<<p->score<<" "<<p->name<<" "<<p->id<<endl;
return 0;
}
set用法的应用:
-
容器中不能有重复元素
-
pair模板的用法
-
pair<T1, T2>
等价于
struct{
T1 first;
T2 second;
};
-
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#include<set>
int main(void){
set<int> st;
int a[10] = {1,2,3,8,7,7,5,6,8,12};
for(int i = 0; i < 10; ++i)
st.insert(a[i]);
cout<<st.size()<<endl;
set<int>::iterator i;
for(i = st.begin(); i != st.end(); ++i)
cout<<*i<<",";
cout<<endl;
pair<set<int>::iterator, bool> result = st.insert(2);
if(! result.second)
cout<<*result.first<<" already exists."<<endl;
else
cout<<*result.first<<" inserted."<<endl;
return 0;
}
multimap的用法:
-
multimap容器里的元素,都是pair形式的
-
multimap<T1, T2> mp;
struct {
T1 first;
T2 second;
};
-
-
multimap里的元素按照first排序,并可以按照first进行查找
应用:
学生成绩录入和查询系统
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#include<set>
#include<map>
struct StudentInfo{
int id;
char name[20];
};
struct Student{
int score;
StudentInfo info;
};
typedef multimap<int, StudentInfo> MAP_STD;
int main(void){
MAP_STD mp;
Student st;
char cmd[20];
while(cin>>cmd){
if(cmd[0] == 'A'){
cin>>st.info.name>>st.info.id>>st.score;
mp.insert(make_pair(st.score, st.info));
}
//make_pair <==> pair<int, StudentInfo>
//first,second <==> int, info
else if(cmd[0] == 'Q'){
int score;
cin>>score;
MAP_STD::iterator p = mp.lower_bound(score);
if(p!=mp.begin()){
--p;
score = p->first;
MAP_STD::iterator maxp = p;
int maxId = p->second.id;
for( ; p != mp.begin() && p->first == score; --p){
if(p->second.id > maxId){
maxp = p;
maxId = p->second.id;
}
}
if(p->first == score){
if(p->second.id > maxId){
maxp = p;
maxId = p->second.id;
}
}
cout<<maxp->second.name<<" "
<<maxp->second.id<<" "
<<maxp->first<<endl;
}
else cout<<"Nobody"<<endl;
}
}
return 0;
}
map例题:
map的用法:
-
不能有关键字重复的元素
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#include<set>
#include<map>
struct Student{
string name;
int score;
};
Student students[5] = {
{"Jack", 89}, {"Tom", 74}, {"Cindy", 87},
{"Alysa", 87}, {"Micheal", 98}};
typedef map<string, int> MP;
int main(){
MP mp;
for(int i = 0; i < 5; ++i)
mp.insert(make_pair(students[i].name,students[i].score));
cout<<mp["Jack"]<<endl;
mp["Jack"] = 60;
for(MP::iterator i = mp.begin(); i != mp.end(); ++i)
cout<<"("<<i->first<<","<<i->second<<") ";
cout<<endl;
Student st;
st.name = "Jack";
st.score = 99;
pair<MP::iterator, bool> p =
mp.insert(make_pair(st.name, st.score));
if(p.second)
cout<<"("<<p.first->first<<","
<<p.first->second<<") inserted"<<endl;
else
cout<<"insertion failed"<<endl;
mp["Harry"] = 78;
MP::iterator q = mp.find("Harry");
cout<<"("<<q->first<<","<<q->second<<")"<<endl;
return 0;
}
map例题:单词词频统计程序
按照出现次数从多到少输出这些单词及其出现的次数,出现次数相同的,字典序靠前的在前面。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#include<set>
#include<map>
struct Word{
int times;
string wd;
};
struct Rule{
bool operator()(const Word & w1, const Word & w2)const{
if(w1.times != w2.times)
return w1.times>w2.times;
else
return w1.wd<w2.wd;
}
};
int main(){
string s;
set<Word, Rule> st;
map<string, int> mp;
while(cin>>s)
++ mp[s];
for(map<string, int>::iterator i = mp.begin();i!=mp.end(); ++i){
Word tmp;
tmp.wd = i->first;
tmp.times = i->second;
st.insert(tmp);
}
for(set<Word, Rule>::iterator i = st.begin();i != st.end(); ++i)
cout<<i->wd<<" "<<i->times<<endl;
return 0;
}