/*
第12章 理解容器与迭代器
STL中的容器是范型结构.贴别适合保存数据集合.容器为模板.
5大类17个容器
顺序容器:
vector
list
deque
array
forward_list
关联容器:
map
multimap
set
multiset
无需容器:
unordered_map
unordered_multimap
unordered_set
unordered_multiset
容器适配器:
queue
priority_queue
stack
bitset
c++的string和流某种程度上也可作为容器
STL容器经常会调用元素的赋值构造函数和复制构造函数,
可将迭代气象香味指向容器中某个元素的指针.
只有顺序容器,关联容器,无序容器提供了迭代器,容器适配器和bitset不支持迭代
const_iterator 和const_reverse_iterator 提供了只读迭代器
vector<int> createVectorofsize(size_t size)
{
vector<int> vec(size); //局部对象
int contents = 0;
for(auto &i :vec) //i遍历过程中获的容器中的每一个元素
i = contents++;
return vec; //生成一个副本
}
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int size =9;
vector<int> vec(size);
int contents = 0;
for(auto &i :vec)
i = contents++;
for(auto i: vec)
cout<<i<<endl;
return 0;
}
#include <iostream>
#include <vector>
using namespace std;
class Element
{
public:
Element(int i,string str):mI(i),mstr(str){}
friend ostream & operator<<(ostream &os,const Element &element);
inline ostream& operator<<(ostream& os){ os<< "inline method"<<mI<<":"<<mstr;return os;}
protected:
int mI;
string mstr;
};
ostream& operator<<(ostream& os,const Element &element)
{
os<<"frient method "<<element.mI<<":"<<element.mstr;
return os;
}
int main()
{
vector<Element> vec; //可以在尾部和任何位置添加
Element myElement(12,"Twelve");
vec.push_back(myElement); //产生副本存入 vector
vec.push_back(Element(12,"Twelve"));//不会产生副本
vec.push_back({12,"Teelve"}); //c++11
vec.emplace_back(12,"Twelve");//放置到位,就地构建对象
for(auto i:vec)
{
cout<<i<<endl;
i<<cout<<endl; //ostream & operator<<(this,const ostream& os)
}
return 0;
}
allocator 指定了内存分配器对象类型
template <class T,class Allocator=allocator<T> >
class vector;
vector至上的operator[]没有边界检查
vector的operator[]返回的是引用,可以用作左值,如果是一个const_vector对象
应用operator[]返回的是一个const元素引用,不能作为赋值目标.
vector 是一动态增长的数组
#include <iostream>
#include <vector>
#include <limits>
using namespace std;
int main()
{
vector<double> doubleVector(10); //固定大小为10, 不自懂增长
vector<double> doublevec(10,0.0);//10 doubles of value 0.0
//-1.79769e+308表示-1.79769134862315乘以10的308次方。
double max = numeric_limits<double>::lowest();
for(size_t i=0;i<10;i++)
{
doubleVector[i]=0;
}
for(size_t i=0;i<7;i++)
{
cout<<"Enter you score:"<<i+1<<":";
cin>>doubleVector[i];
if(doubleVector[i]>max)
{
max = doubleVector[i];
}
}
max /=100.0;
for(size_t i = 0; i<10;i++)
{
doubleVector[i]/=max;
cout<<doubleVector[i]<<" ";
}
return 0;
}
#include <iostream>
#include <vector>
#include <limits>
using namespace std;
int main()
{
vector<double> doubleVector;
double max = numeric_limits<double>::lowest();
for(size_t i=0;true;i++)
{
double temp;
cout<<"Enter you score:"<<i+1<<":";
cin>>temp;
if( temp <0 || temp>100)
{
break;
}
doubleVector.push_back(temp);
if(temp>max)
{
max =temp;
}
}
max /=100.0;
for(size_t i = 0; i<doubleVector.size();i++)
{
doubleVector[i]/=max;
cout<<doubleVector[i]<<" ";
}
return 0;
}
c++ vector<int> intvector({1,2,23,4,5,6});
vector<int> intvector={1,2,3,4,5};
在heap上分配vector:
vector<element> *elementvector = new vector<element>(10);
delete elementvector;
通过只能指针自动释放vector
模板类 对象
shared_ptr<vector<elment> > elementvector(new vector<element>(10));
vector<int> intVector(10,0);
othercode....
intVector.assign(5,100);//删除10个元素 取而代之的是5个值为100的元素
c++11 initializer_list 初始化列表
intVector.assign({1,23,3,4,5});
#include <iostream>
#include <vector>
#include <limits>
using namespace std;
int main()
{
vector<int> vectorone(10,0);
vector<int> vectortwo(5,100);
vectortwo.swap(vectorone); //交换两个vector内容
for(size_t i=0;i<vectortwo.size();i++)
{
cout<<vectortwo[i]<<" ";
}
}
迭代器:
for(vector<double>::iterator iter= doubleVector.begin();iter!=doubleVector.end();i++)
{
*iter /=max;
cout<<*iter<<" ";
}
for (auto &d: doubleVector)
{
d/=max;
cout<<d<<" ";
}
#include <iostream>
#include <vector>
#include <limits>
#include <string>
using namespace std;
int main()
{
vector<string> stringVector(10,"hello");
for(auto it=stringVector.begin();it!=stringVector.end();++it)
{
it->append("there");
}
for(auto& str: stringVector)
{
cout<<str<<endl;
}
//const_iterator 不能转化为 iterator
//vector<type>::const_iterator it = myVector.begin();
//c++ 11
//vector<string> stringVector(10,"hello");
for(auto iter = stringVector.cbegin();iter!=stringVector.cend();++iter)
{
cout<<*iter<<endl;
}
vector<int> intVector;
auto it = intVector.begin(); //end() 返回的是尾部指针
*it = 10; //BUG it doesn't refer to a valid alement
}
insert()的三种不同方式:
1 插入一个元素 2 插入单个元素n个副本 3 从一个迭代哦器范围插入
insert(const_iterator pos,const T& x);
insert(const_isterator pos,size_type n,const T& x)
insert(const_iterator pos,InputIterator frist,InputIterator last)
#include <iostream>
#include <vector>
#include <limits>
#include <string>
using namespace std;
void printVector(vector<int> &vec)
{
for(auto &i: vec)
{
cout<<i<<" ";
}
}
int main()
{
vector<int> vectorone ={1,2,3,5};
vector<int> vectortwo;
vectorone.insert(vectorone.begin()+3,4);
for(int i=6;i<=10;i++)
vectortwo.push_back(i);
printVector(vectorone);
printVector(vectortwo);
vectorone.insert(vectorone.end(),vectortwo.begin(),vectortwo.end());
printVector(vectorone);
vectorone.erase(vectorone.begin()+1,vectorone.begin()+5);
printVector(vectorone);
vectortwo.clear();
vectortwo.insert(vectortwo.begin(),10,100);
vectortwo.pop_back();
printVector(vectortwo);
}
vector 内部的重新分配会导致引用vector种元素的所有迭代器失效
capacity() 返回在vector再重新分配之前可以保存元素的个数
还能存多少数据: capacity()-size();
时间片轮转调度的类: 保存进程的列表
RoundRobin类模板
#include <iostream>
#include <vector>
#include <limits>
#include <string>
#include <unistd.h>
using namespace std;
template <typename T>
class RoundRobin
{
public:
RoundRobin(int numExpected=0);
virtual ~RoundRobin();
void add(const T& elem);
void remove(const T& elem);
T& getNext() throw(std::out_of_range);
protected:
std::vector<T> mElemes;
//当访问基于一个或多个模板参数的类型时 必须显示的指定typename
typename std::vector<T>::iterator mCurElem;
private:
RoundRobin(const RoundRobin &src); //防止拷贝和赋值
RoundRobin & operator =(const RoundRobin& rhs);
};
template <typename T>
RoundRobin<T>::RoundRobin(int numExpected)
{
mElemes.reserve(numExpected);
mCurElem = mElemes.begin();
}
template <typename T>
RoundRobin<T>::~RoundRobin()
{}
template <typename T>
void RoundRobin<T>::add(const T& elem)
{
//这个地方看不明白
int pos = mCurElem - mElemes.begin();
mElemes.push_back(elem);
mCurElem = mElemes.begin()+pos;
}
template <typename T>
void RoundRobin<T>::remove(const T& elem)
{
for(auto it = mElemes.begin();it!=mElemes.end();it++)
{
if(*it == elem)
{
int newpose;
if(mCurElem <= it)
{
newpose = mCurElem-mElemes.begin();
}else{
newpose = mCurElem-mElemes.begin()-1;
}
mElemes.erase(it);
mCurElem = mElemes.begin()+newpose;
if(mCurElem == mElemes.end())
{
mCurElem = mElemes.begin();
}
return ;
}
}
}
//资源遍历
template <typename T>
T& RoundRobin<T>::getNext() throw (std::out_of_range)
{
if(mElemes.empty())
throw std::out_of_range("No elemet in the list");
T& retval = *mCurElem;
++mCurElem;
if(mCurElem == mElemes.end())
mCurElem = mElemes.begin();
return retval;
}
//进程类
class Process
{
public:
Process(const string& name):mName(name){}
void doworkDuringTimeSlice()
{
cout<<"process"<<"--->"<<mName<<" "<<"performing work during time slice"<<endl;
}
bool operator ==(const Process& rhs)
{
return mName == rhs.mName;
}
protected:
string mName;
};
//进程安排
class Scheduler
{
public:
Scheduler(const vector<Process>& processes);
void scheduleTimeSlice();
void removeProcess(const Process& process);
protected:
//时间片轮转的类 的对象rr
RoundRobin<Process> rr;
};
Scheduler::Scheduler(const vector<Process>& processes)
{
for(auto& process: processes)
rr.add(process);
}
void Scheduler::scheduleTimeSlice()
{
try{
rr.getNext().doworkDuringTimeSlice();
}catch(const out_of_range)
{
cerr<<"No more process to schedule."<<endl;
}
}
void Scheduler::removeProcess(const Process &process)
{
rr.remove(process);
}
int main(){
//存放进程的对象
vector<Process> processes = {Process("one"),Process("Two"),Process("Three"),Process("Four")};
//执行进程 模拟cpu
Scheduler sched(processes);
for(int i=0;true;i++)
{
sleep(1);
sched.scheduleTimeSlice();
}
sched.removeProcess(processes[1]);
cout<<"Remove second process"<<endl;
for(int i=0;i<4;i++)
sched.scheduleTimeSlice();
return 0;
}
#include <list>
#include <iostream>
using namespace std;
//list 没有提供operator[]只有通过迭代器访问单个数据
//list 本质是链表
int main()
{
list<string> dictionary,bword;
dictionary.push_back("afjdsah");
dictionary.push_back("afkjsad");
dictionary.push_back("canfgdj");
dictionary.push_back("cjjjjsdljk");
bword.push_back("bath");
bword.push_back("baldjklsd");
if(bword.size()>0)
{
auto iterLastB = --(bword.end());
list<string>::iterator it;
for(it = dictionary.begin();it!=dictionary.end();it++)
{
if(*it > *iterLastB)
break;
}
//splice 实现list的拼接 void splice(iterator positon,list<T, Allocator>&x);
// void splice (iterator position,list<T,Allocator>& x,iterator i)
//void splice(iterator position ;list<T,Allocator>& x,iterator frist, iterator second)
dictionary.splice(it,bword);
}
for(auto it = dictionary.cbegin();it!=dictionary.cend();it++)
{
cout<<*it<<endl;
}
return 0;
}
*/
list <string>
getTotalEnrollment(const vector<list<string> > & courseStudents,const list<string>& dropStudents)
{
list<sting> allstudents;
for(auto &lst: courseStudents)
{
allstudents.insert(allstudents.end(),lst.begin(),lst.end());
}
allstudents.sort();
allstudents.unique(); //删除”所有相邻的重复元素。
for(auto& str:dropStudents)
{
allstudents.remove(str);
}
return allstudents;
}