Week 12
12.1 STL排序算法sort
STL概述
- STL: (Standard Template Library) 标准模板库
- 包含一些常用的算法如排序查找,还有常用的数据结构如可变长数组、链表 、字典等。
- 使用方便,效率较高
- 要使用其中的算法,需要#include <algorithm>
sort 排序
int a[] = {15,4,3,9,7,2,6}; sort(a,a+7); //对整个数组从小到大排序
int a[] = {15,4,3,9,7,2,6}; sort(a,a+3); // 结果:{3,4,15,9,7,2,6}
int a[] = {15,4,3,9,7,2,6}; sort(a+2,a+5); //结果:{15,4,3,7,9,2,6}
从大到小
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
struct Student {
char Name[20];
int ID;
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 Rule1 { //按姓名从小到大排
bool operator()(const Student & s1, const Student & s2) {
if (stricmp(s1.Name, s2.Name) < 0)
return true;
return false;
}
};
struct Rule2 { //按id从小到大排
bool operator()(const Student & s1, const Student & s2) {
return s1.ID < s2.ID;
}
};
struct Rule3 { //按gpa从高到低排
bool operator()(const Student & s1, const Student & s2) {
return s1.GPA > s2.GPA;
}
};
void Print(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()
{
int n = (sizeof(Students) / sizeof(Student));
sort(Students, Students + n, Rule1());
Print(Students, n);
sort(Students, Students + n, Rule2());
Print(Students, n);
sort(Students, Students + n, Rule3());
Print(Students, n);
return 0;
}
12.2 STL二分查找算法
STL提供在排好序的数组上进行二分查找的算法
- binary_search
- lower_bound
- upper_bound
binary_search
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
void Print(int a[], int size)
{
for (int i = 0; i < size; ++i)
cout << a[i] << ",";
cout << endl;
}
struct Rule {
bool operator()(const int & s1, const int & s2) {
return s1 % 10 < s2 % 10;
}
};
int main()
{
int a[] = { 12,45,3,98,21,7,100 };
sort(a, a + sizeof(a) / sizeof(int));
Print(a, sizeof(a) / sizeof(int));
cout << "result:" << binary_search(a, a + sizeof(a) / sizeof(int), 12) << endl;
cout << "result:" << binary_search(a, a + sizeof(a) / sizeof(int), 77) << endl;
sort(a, a + sizeof(a) / sizeof(int), Rule());
Print(a, sizeof(a) / sizeof(int));
cout << "result:" << binary_search(a, a + sizeof(a) / sizeof(int), 7) << endl;
cout << "result:" << binary_search(a, a + sizeof(a) / sizeof(int), 8, Rule()) << endl;
return 0;
}
倒数第二个result是0是因为没有给出查找规则,就默认按照从小到大的排列方式进行二分查找。
而最后一个result是1是因为按照Rule的规则,是按照个位数的大小排序,而8不是必须在98前面,也不是必须在98后面,所以8“等于”98。即:由于98和8的个位数都相同,程序认为他们“相等”,认为它能找到8,但是实际上找到的是98。
lower_bound
upper_bound
12.3 multiset
STL中的平衡二叉树数据结构
multiset
multiset用法实例
#include <iostream>
#include <cstdio>
#include <string>
#include <set> //使用multiset和set需要此头文件
using namespace std;
int main()
{
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]); //插入的是a [i]的复制品
multiset<int>::iterator i; //迭代器,近似于指针
for (i = st.begin(); i != st.end(); ++i)
cout << *i << ",";
cout << endl;
i = st.find(22); //查找22,返回值是迭代器
if (i == st.end()) //找不到则返回值为 end()
cout << "NOT FOUND!" << endl;
else
cout << "FOUND:" << *i << endl; //找到则返回指向找到的元素的迭代器
i = st.insert(22); //插入 22
i = st.find(22);
if (i == st.end())
cout << "NOT FOUND!" << endl;
else
cout << "FOUND:" << *i << endl;
for (i = st.begin(); i != st.end(); ++i)
cout << *i << ",";
cout << 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 << ",";
cout << endl;
return 0;
}
12.4 自定义排序规则的multiset用法
#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <functional>
using namespace std;
struct Rule {
// bool operator()(const int & s1, const int & s2)const {
bool operator()(const int & s1, const int & s2) {
return (s1 % 10) < (s2 % 10);
}
};
int main()
{
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;
i = st.find(133);
if (i == st.end())
cout << "NOT FOUND!" << endl;
else
cout << "FOUND:" << *i << endl;
multiset<int, Rule> st2;
for (int i = 0; i < 10; ++i)
st2.insert(a[i]);
multiset<int, Rule>::iterator p;
for (p = st2.begin(); p != st2.end(); ++p)
cout << *p << ",";
cout << endl;
p = st2.find(133);
if (p == st2.end())
cout << "NOT FOUND!" << endl;
else
cout << "FOUND:" << *p << endl;
return 0;
}
我自己码的代码不知道为啥会报错,检查了好几遍没问题呀!复制了老师的代码也出错,好想在这里@他。。。
哈哈哈哈,上边的问题解决了!我是看了这篇文章之后有了点想法的其实,只要加一个const就好,心里路程那篇文章里有写。我认为最有用的一句话是
否则就会导致丢失const限定符的错误 因此解决办法就是给operator()加上const属性
12.5 set
#include <cstdio>
#include <cstring>
#include <set>
using namespace std;
int main()
{
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;
}