关闭

c++primer学习笔记 ( 第九章 顺序容器)

标签: c++iteratorstringvectorfunlist
972人阅读 评论(0) 收藏 举报
分类:

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迭代器和迭代器范围

一定要注意vectordeque提供了额外的运算!!

iter+niter-niter1+=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函数  加到整个容器前面。只有listdeque可以,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所指向的元素的前面插入有be两个迭代器标记范围之内的元素。返回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


永远记住,添加元素可能会使迭代器失效,小心使用endbegin

习题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(预留空间)成员。

capacitysize不同,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等等。。好啰嗦啊~~

::>_<::~~不打了~~~

。。。。。。


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:603284次
    • 积分:8639
    • 等级:
    • 排名:第2203名
    • 原创:255篇
    • 转载:13篇
    • 译文:0篇
    • 评论:134条
    最新评论