9.1顺序容器的定义
#include<vector>
#include<list>
#include<deque>
vector<int> ivec; //定义一个空的vector<int>类型,
vector<int> ivec2(ivec); //复制初始化
vector ivec2(ivec); // 同上
vector<int> ivec(10); // 十个零
vector<int>ivec(10,1); //十个一
vector<int> ivec(vec.begin(),vec.end()) //用两个迭代器复制初始化
const list<int>::size_type list_size=64;
list<string> slist(list_size,"ee"); //64个字符串,每个都是ee
容器内的元素类型必须是 1)支持赋值运算,2)支持复制
容器的容器
vector<vector<int> .> lines; // attention!!!!这里> .> 之间必须有空格!!
9.2迭代器和迭代器范围
一定要注意vector和deque提供了额外的运算!!
如iter+n,iter-n,iter1+=iter2,>,<,>=,<=等.
而list只提供了自增,自减,解引用,==,!=,运算,。
计算vector对象中点位置:
ector<int>::iterator iter=vec.begin() +vec.size()/2;
习题9.9
#include<iostream>
#include<list>
using namespace std;
int main(){
list<int> ilis;
int a;
cout<<"请输入一组数组(ctrl+z to end):";
while(cin>>a)
ilis.push_back(a);
cout<<"原来的数组为:\n";
list<int>::iterator iter=ilis.begin();
while(iter!=ilis.end())
cout<<*(iter++)<<" ";
cout<<endl;
cout<<"逆序之后数组为:\n";
list<int>::iterator iter2=ilis.end();
while(iter2!=ilis.begin())
cout<<*(--iter2)<<" ";
cout<<endl;
}
迭代起的范围是[first,end),左闭合区间。当first=end时候空,其他时候,first是指向第一个元素,end是指向最后一个元素的下一个地址。
last绝对不会在end之前。
习题9.11
#include<iostream>
#include<vector>
using namespace std;
bool Fun(vector<int>::iterator,vector<int>::iterator,int);
int main(){
vector<int> ivec;
int c;
for(int i=0;i<100;i++)
ivec.push_back(i);
cout<<"原来的数组为:\n";
vector<int>::iterator iter=ivec.begin();
while(iter!=ivec.end())
cout<<*(iter++)<<" ";
cout<<endl;
int a,b;
cout<<"请输入要查找的范围(如1 40):\n";
cin>>a>>b;
vector<int>::iterator iter1=ivec.begin()+a,iter2=ivec.begin()+b;
cout<<"请输入要查找的数:\n";
cin>>c;
if(Fun(iter1,iter2,c))
cout<<"Found it.";
else
cout<<"Not found it.";
cout<<endl;
}
bool Fun(vector<int>::iterator iter1,vector<int>::iterator iter2,int a){
while(iter1!=iter2){
if(*(iter1)==a)
return 1;
iter1++;
}
}
习题9.12
#include<iostream>
#include<vector>
using namespace std;
vector<int>::iterator Fun(vector<int>::iterator,vector<int>::iterator,int);
int main(){
vector<int> ivec;
int c;
for(int i=0;i<100;i++)
ivec.push_back(i);
cout<<"原来的数组为:\n";
vector<int>::iterator iter=ivec.begin();
while(iter!=ivec.end())
cout<<*(iter++)<<" ";
cout<<endl;
int a,b;
cout<<"请输入要查找的范围(如1 40):\n";
cin>>a>>b;
vector<int>::iterator iter1=ivec.begin()+a,iter2=ivec.begin()+b;
cout<<"请输入要查找的数:\n";
cin>>c;
if(Fun(iter1,iter2,c)!=iter2)
cout<<"Found it.";
else
cout<<"Not found it.";
cout<<endl;
}
vector<int>::iterator Fun(vector<int>::iterator iter1,vector<int>::iterator iter2,int a){
while(iter1!=iter2){
if(*(iter1)==a)
return iter1;
iter1++;
}
return iter2;
}
习题9.14
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int main(){
string str;
vector<string> ivec;
while(cin>>str)
ivec.push_back(str);
vector<string>::iterator iter=ivec.begin();
while(iter!=ivec.end())
cout<<*iter++<<" ";
cout<<endl;
}
习题9.15
#include<iostream>
#include<list>
#include<string>
using namespace std;
int main(){
string str;
list<string> ivec;
while(cin>>str)
ivec.push_back(str);
list<string>::iterator iter=ivec.begin();
while(iter!=ivec.end())
cout<<*iter++<<" ";
cout<<endl;
}
使用迭代器的时候,一定要注意那些操作可以使迭代器失效!!只要有元素的添加和删除,begin或者end的结果会失效!!最好载重新定值。
9.3顺序容器的操作
在顺序容器上添加元素:
push_back函数 加到整个容器后面。三个顺序容器都可以
push_front函数 加到整个容器前面。只有list和deque可以,vector就不可以。
#include<iostream>
#include<list>
using namespace std;
int main(){
list<int> ilis;
int a;
while(cin>>a)
ilis.push_front(a);
list<int>::iterator fir=ilis.begin(),last=ilis.end();
while(fir!=last)
cout<<*(fir++)<<" ";
cout<<endl;
}
容器元素都是副本.
在容器指定位置插入元素:
insert函数,三种形式。\
1)c.insert(p,t) 在p所指向的元素的前面插入元素t 返回新添加元素的迭代器。
2)c.insert(p,n,t) 在p所指向的元素的前面插入n个值为t的元素 返回void
3)c.insert(p,b,e) 在p所指向的元素的前面插入有b的e两个迭代器标记范围之内的元素。返回void
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int main(){
string a[4]={"as","bs","cs","ds"};
vector<string> ivec;
ivec.insert(ivec.end(),10,"hehe"); //第二种用法
ivec.insert(ivec.end(),a,a+4); //第三种用法
vector<string>::iterator fir=ivec.begin(),last=ivec.end();
while(fir!=last)
cout<<*fir++<<" ";
cout<<endl;
vector<string>::iterator iter=ivec.insert(ivec.begin(),"nihao"); //第一种用法
cout<<*iter<<endl;
return 0;
}
妙用insert还可以把他当成push_front来用!
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int main(){
vector<string> ivec;
string word;
vector<string>::iterator iter=ivec.begin();
while(cin>>word)
iter=ivec.insert(iter,word);
vector<string>::iterator fir=ivec.begin(),last=ivec.end();
while(fir!=last)
cout<<*fir++<<" ";
return 0;
} //等效于push_front
永远记住,添加元素可能会使迭代器失效,小心使用end和begin
习题9.18
#include<iostream>
#include<list>
#include<deque>
using namespace std;
int main(){
list<int> ilis;
for(int i=0;i<100;i++)
ilis.push_back(i);
deque<int> ideq1,ideq2;
for(list<int>::iterator iter=ilis.begin();iter!=ilis.end();iter++){
if(*iter%2==0) ideq1.push_back(*iter);
else ideq2.push_back(*iter);
}
for(deque<int>::iterator fir=ideq1.begin();fir<ideq1.end();fir++)
cout<<*fir++<<" ";
cout<<endl;
for(deque<int>::iterator sec=ideq2.begin();sec<ideq2.end();sec++)
cout<<*sec++<<" ";
cout<<endl;
return 0;
}
习题9.20
#include<iostream>
#include<list>
#include<deque>
#include<vector>
using namespace std;
int main(){
vector<int> ivec;
for(int i=0;i<10;i++)
ivec.push_back(i);
list<int> ilis;
for(int i=0;i<10;i++)
ilis.push_back(i);
vector<int>::iterator iter1=ivec.begin();
list<int>::iterator iter2=ilis.begin();
while(iter1!=ivec.end()&&iter2!=ilis.end()){
if(*iter1!=*iter2) break;
iter1++;
iter2++;
}
if(iter1==ivec.end()&&iter2==ilis.end())
cout<<"两容器内元素相同。";
else
cout<<"两容器内元素不相同。" ;
}
容器大小的操作
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int> ivec;
for(int i=0;i<10;i++)
ivec.push_back(i);
if(ivec.empty())
cout<<"容器为空"<<endl;
else cout<<"容器不为空"<<endl;
cout<<ivec.size()<<endl;
ivec.resize(100,12);
for(vector<int>::iterator fir=ivec.begin();fir<ivec.end();fir)
cout<<*fir++<<" ";
cout<<endl<<ivec.size()<<endl;
ivec.resize(10); //删去后90个,只要前面10个
cout<<endl<<ivec.size()<<endl; //输出10
for(vector<int>::iterator fir=ivec.begin();fir<ivec.end();fir)
cout<<*fir++<<" "; //输出前十个
}
访问元素
如果一个容器非空:
c.back(); 返回最后一个元素的引用
c.front(); 返回第一个元素的引用
c[n]; 返回第n个元素的引用
c.at(n); 返回第n个元素的引用
习题9.24
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int> ivec;
int i;
while(cin>>i)
ivec.push_back(i);
if(ivec.empty())
{
cout<<"The continer is empty,Error!"<<endl;
return 0;
}
cout<<ivec[0]<<endl;
cout<<ivec.at(0)<<endl;
cout<<ivec.front()<<endl;
cout<<*ivec.begin()<<endl;
}
删除元素:
c.erase(p)
c.erase(b,e)
c.clesr() //删除所有元素
c.pop_back(); //删除最后一个元素,返回void
c.pop_front(); //删除第一个元素,返回void
#include<iostream>
#include<list>
#include<vector>
using namespace std;
int main(){
vector<int> ivec;
list<int> ilis;
int a[]={0,1,1,2,3,5,8,13,21,55,89};
int len=sizeof(a)/4;
for(int i=0;i<len;i++)
ivec.push_back(a[i]);
for(int i=0;i<len;i++)
ilis.push_back(a[i]);
for(vector<int>::iterator iter=ivec.begin();iter!=ivec.end();iter++){
if((*iter)%2!=0){
iter=ivec.erase(iter);//返回删除元素后一个元素的迭代器
--iter;//注意迭代器回退
}
}
for(list<int>::iterator iter2=ilis.begin();iter2!=ilis.end();iter2++){
if((*iter2)%2==0){
iter2=ilis.erase(iter2); //返回删除元素后一个元素的迭代器
--iter2; //注意迭代器回退
}
}
cout<<"容器vector里面的元素依次是:\n";
for(vector<int>::iterator iter=ivec.begin();iter!=ivec.end();iter++)
cout<<*iter<<" ";
cout<<endl;
cout<<"容器list里面的元素依次是:\n";
for(list<int>::iterator iter2=ilis.begin();iter2!=ilis.end();iter2++)
cout<<*iter2<<" ";
cout<<endl;
return 0;
}
习题9.28
#include<iostream>
#include<list>
#include<vector>
#include<string>
using namespace std;
int main(){
char* a[]={"213","sdaf","asdffweewqr","ddeds"};
list<char*> ilis(a,a+4);
vector<string> ivec;
string str;
ivec.assign(ilis.begin(),ilis.end());
for(list<char*>::iterator lit=ilis.begin();lit!=ilis.end();++lit)
cout<<*lit<<" ";
cout<<endl;
for(vector<string>::iterator iter2=ivec.begin();iter2!=ivec.end();++iter2)
cout<<*iter2<<" ";
cout<<endl;
}
9.4 vector容器的自增长
capacity(容量) 与 reserve(预留空间)成员。
capacity与size不同,capacity是容器在必须分配新的存储空间之前的最大存储的元素个数,而size是当前容器拥有的元素个数。
习题9.30 编写程序研究vector的内存分配策略~~
#include<iostream>
#include<list>
#include<vector>
#include<string>
using namespace std;
int main(){
vector<int> ivec;
cout<<"ivec:size:"<<ivec.size();
cout<<"ivec.capcity:"<<ivec.capacity()<<endl;
ivec.push_back(1);
cout<<"ivec:size:"<<ivec.size();
cout<<"ivec.capcity:"<<ivec.capacity()<<endl;
for(int i=0;i<50;++i)
{
ivec.push_back(i);
cout<<"ivec:size:"<<ivec.size()<<" ";
cout<<"ivec.capcity:"<<ivec.capacity()<<endl;
}
}
9.5容器的选用
list容器其实就是链表,适合插入删除,不适合随机访问。
vector容器只适合随机访问和在尾部插入删除。
deque则是适合随机访问和在头部尾部插入删除。
通常来说,除非我们找到了非要选择其他容器不可的理由,否则,vector容器是最好的选择。
9.6再谈string类型
之前学过这些:
string s;
string s(cp);
string s(s2);
is>>a;
os>>s;
getline(is,s);
s1+s2;
s1+=s2;
string类型可以看作字符容器。
习题9.35
#include<iostream>
#include<string>
using namespace std;
int main(){
string line;
char a='a';
char b='B';
for(int i=0;i<10;++i)
{
line.push_back(a);
line.push_back(b);
}
for(string::iterator iter=line.begin();iter!=line.end();++iter)
cout<<*iter<<" ";
cout<<endl;
for(string::iterator iter=line.begin();iter!=line.end();++iter)
if(isupper(*iter))
{ line.erase(iter);
--iter; //erase 返回删除元素的下一个指针。。。。。attention!!!
}
for(string::iterator iter=line.begin();iter!=line.end();++iter)
cout<<*iter<<" ";
cout<<endl;
}
习题9.36
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int main(){
vector<char> ivec(10,'a');
string str(ivec.begin(),ivec.end());
for(vector<char>::iterator iter=ivec.begin();iter!=ivec.end();iter++)
cout<<*iter<<" ";
return 0;
}
附录:itoa函数,把一个数字转化成char数组类型
#include<iostream>
using namespace std;
int main(){
int a;
cin>>a;
char str[22];
itoa(a,str,10);
cout<<str<<endl;
int i=0;
string s;
for(string::iterator iter=s.begin();iter!=s.end();iter++,i++)
s.push_back(str[i]);
cout<<a;
return 0;
}
string与容器共有的操作:
s.insert(p,t)
s.insert(p,n,t)
s.insert(p,b,e)
s.assign(b,e)
s.assign(n,t)
s.erase(p)
s.erase(b,e)
string类型特有的版本:
s.insert(pos,n,c)
s.insert(pos,s2)
s.insert(pos,s2,pos2,len) 其实这个操作可以对应到 s.insert(p,b,e) 这个操作,
s.assign(s2)
s.assign(s2,pos2,len) 这个可以对应 s.assign(b,e)
s.assign(cp,len)
s.assign(cp)
s.erase(pos,len) 这个可以对应 s.erase(b,e)
只是用于string类型的操作
s.substr(pos,n);
s.substr(pos);
s.substr();
修改string对象的操作:
s.append(args); //args是一个字符串
s.repleace(pos.len,args);
s.repleace(b,e,args);
举例说明:
#include<iostream>
#include<string>
using namespace std;
int main(){
string a="today is ";
a.insert(0,10,'a'); //在第一个元素之前插入十个a
cout<<a<<endl;
a.assign(4,'b'); //用4个b初始化a
cout<<a<<endl;
a="today is ";
string b=a.substr(0,2); //b是a的第一个字符开始的两个字符
cout<<b<<endl;
b=a.substr(4); //b是a 第五个元素及以后组成的字符串
cout<<a<<endl<<b<<endl;
a.append("goddamn"); //在a后面添加goddamn
cout<<a<<endl;
a.replace(0,8,"shit "); //把a中第一个到第九个字符替换成shit
cout<<a<<endl;
}
还有compare等等。。好啰嗦啊~~
::>_<::~~不打了~~~
。。。。。。