容器的概念:
序列式容器:容器的元素的位置是由进入容器的时机和地点来决定的
关联式容器:容器已有规则,进入元素由容器内规则决定。
迭代器的概念:
可以先理解为指针,对指针的基本操作都可以对迭代器进行。
但实际上迭代器是一个类。这个类封装一个指针
算法的概念:
通过有限的步骤解决问题。
分离设计:
通过一个小案例初步理解算法容器分开设计,由迭代器进行链接:
#include<iostream>
using namespace std;
//容器算法分开设计,通过迭代器链接:
int mycount(int* start,int * end,int val) //算法统计统计容器内元素的个数
{
int num = 0;
while (start != end)
{
if (*start == val)
num++;
start++;
}
return num;
}
int main()
{
int arr[] = { 0,12,4,512,0};
int* Abegin = arr; //迭代器开始位置
int* Aend = &(arr[sizeof(arr) / sizeof(int)]);
int num = mycount(Abegin, Aend, 0);
cout << num;
}
容器-string容器:
string封装了char*,是一个char*的容器
string容器不需要考虑内存释放和越界
char*和string之间可以通过string提供的c_str()进行转换
string较为简单,个人认为需要了解的操作:
substr(int pos = 0,int n = npos)const;//返回由pos开始的n个字符组成的字符串
容器-vector容器:
可称动态数组或者可变数组,支持随机访问,迭代器可以直接+2,-3等
迭代器除了v.begin()和v.end()之外还有v.rend(指向第一个元素的前一个位置)和v,rbegin(指向最后一个元素)
访问数组元素尽量用at,如果错误会抛出异常,[]则不会
vector容器也比较简单,需要了解下用swap函数收缩空间,以及reserve预留空间
容器-deque容器:
双端数组,除了尾插push_back尾删pop_back之外还有头插push_front和头删pop_front
也支持随机存储
通过小案例了解deque和vector:
#include<iostream>
#include<algorithm>
#include<vector>
#include<deque>
using namespace std;
class Person //创建选手类
{
public:
Person();
Person(int score, string name);
~Person();
public:
int Pscore;
string Pname;
};
Person::Person()
{
Pscore = 0;
Pname = " ";
}
Person::Person(int score, string name):Pname(name),Pscore(score)
{
}
Person::~Person()
{
}
void SetPerson(vector<Person>& v)//创建选手
{
string nameseed = "ABCDE";
for(int i = 0;i<5;i++)
{
Person p;
p.Pname = "选手";
p.Pname += nameseed[i];
p.Pscore = 0;
v.push_back(p);
}
}
void SetScore(vector<Person>& v) //打分
{
for (vector<Person>::iterator it = v.begin(); it != v.end(); ++it)
{
deque<int>dScore;
for (int i = 0; i < 10; ++i)
{
int score = rand() % 41 + 60;
dScore.push_back(score);
}
dScore.pop_back();
dScore.pop_front();
int sumScore = 0;
int AvgScore = 0;
for (deque<int>::iterator itt = dScore.begin(); itt != dScore.end(); ++itt)
{
sumScore += (*itt);
}
AvgScore = sumScore / dScore.size();
(*it).Pscore = AvgScore;
}
}
bool Paixu(const Person& p1, const Person& p2)
{
return p1.Pscore > p2.Pscore;
}
void Mysort(vector<Person>& v) //降序排列
{
sort(v.begin(), v.end(), Paixu);
for (vector<Person>::iterator it = v.begin(); it != v.end(); ++it)
{
cout << "姓名: " << (*it).Pname << " 得分: " << (*it).Pscore << endl;
}
}
int main()
{
vector<Person>v1;
SetPerson(v1);
SetScore(v1);
Mysort(v1);
}
容器-stack容器(栈容器):
不提供迭代器->不能遍历,不支持随机存取
可以返回栈顶元素
容器-queue容器(队列容器):
不提供迭代器->不能遍历,不支持随机访问
可以放回队尾或者队头元素
容器-list:
链表由一系列结点组成,结点包含数据域跟指针域。内存是非连续存储的。
链表只有在需要的时候才分配内存,链表还需要额外的空间保存结点的前驱后继关系
set/multiset容器:
set容器的元素既是键值又是实值。
基于红黑树 set容器不允许元素重复,而multiset允许
不能通过set的迭代器改变元素的值
set查找操作:
lower_bound(keyElem) //返回第一个key>=keyElem元素的迭代器
upper_bound(keyElem) //返回第一个key>keyElem元素的迭代器
equal_range(keyElem) //返回容器中key与keyElem相等的上下限的两个迭代器(就是上面两个一起返回)用对组接收
map/multimap容器:
map具有键值跟实值,所有元素根据键值排序,底层也是红黑树。
map不允许重复key,而multimap允许。
map中存的都是对组
示例:
#include<algorithm>
#include<vector>
#include<map>
#include<time.h>
#include<stdio.h>
using namespace std;
#define SALE_DEPATMENT 1//销售部门
#define DEVELOP_DEPATMENT 2//研发部门
#define FINACIAL_DEPATMENT 3//财务部门
class Worker {
public:
string Wname;
int Wage;
int Wsalary;
string Wtele;
};
void CreatWorker(vector<Worker>& v) //创建员工
{
string nameseed = "ABCDE";
for (int i = 0; i < 5; i++)
{
Worker w;
w.Wname = "员工";
w.Wname += nameseed[i];
w.Wtele = "8208798";
w.Wage = rand() % 10 + 30;
w.Wsalary = rand() % 10000 + 10000;
v.push_back(w);
}
}
void WorkerBygroup(vector<Worker>& v, multimap<int, Worker>& m) //进行分组
{
for (vector<Worker>::iterator it = v.begin(); it != v.end(); it++)
{
int depatID = rand() % 3+1;
switch (depatID)
{
case SALE_DEPATMENT:
m.insert(make_pair(SALE_DEPATMENT, *it));
break;
case DEVELOP_DEPATMENT:
m.insert(make_pair(DEVELOP_DEPATMENT, *it));
break;
case FINACIAL_DEPATMENT:
m.insert(make_pair(FINACIAL_DEPATMENT, *it));
break;
default:
break;
}
}
}
void showgropuworker(int depatID, multimap<int, Worker>& m)
{
multimap<int, Worker>::iterator it = m.find(depatID);
int count = m.count(depatID);
int num = 0;
for (multimap<int, Worker>::iterator pos = it; it != m.end() && num < count; pos++, num++)
{
cout << "姓名: " << (*pos).second.Wname << " 年龄: " << (*pos).second.Wage
<< "电话" << (*pos).second.Wtele << "工资: " << (*pos).second.Wsalary << endl;
}
}
void PrintBygropu(multimap<int, Worker>& m)
{
cout << "销售部门" << endl;
showgropuworker(SALE_DEPATMENT, m);
cout << "研发部门" << endl;
showgropuworker(DEVELOP_DEPATMENT, m);
cout << "财务部门" << endl;
showgropuworker(FINACIAL_DEPATMENT, m);
}
int main()
{
vector<Worker>v1;
multimap<int,Worker>m1;
//创建员工
CreatWorker(v1);
//员工分组
WorkerBygroup(v1, m1);
//打印员工信息
PrintBygropu(m1);
}
初次了解STL,这条路还很长,笔记先到这吧
补充:
非常考验STL基础