本文答案,部分参考于C++ Primer 习题集
第一章
第二章
第三章
第四章
第五章
第六章
第七章
第八章
按字典序插入到容器中,意味着进行插入排序操作,从而需要在容器内部频繁进行插入操作,vector在尾部之外的位置插入和删除元素很慢,deque 在头尾之外的位置插入和删除元素很慢.而list在任何位置插入和删除速度都很快.因此,这个任务选择list更为合适.当然,如果不是必须边读取单词边插入到容器中.可以使用vector,将读入的单词一次追加到尾部,读取完毕后,调用标准库到排序算法将到此重排为字典序.
由于需要在头,尾.分别进行插入,删除操作,因此将vecotor排除在外.
deque和list都可以达到很好的性能.如果还需要频繁进行随机访问,则deque更好.
由于整数占用空间很小.且快速的排序算法需频繁随机访问元素,将list排除在外,由于无需在头部进行插入,删除操作.因此使用vector即可.无须使用deque.
list> a;
两个迭代器begin和end必须指向同一个元素中的元素,或者是容器最后一个元素之后的位置,而且,对begin反复进行递增操作,可保证达到end,即end不在begin之前.
#include
#include
#include
#include
using namespace std;
bool Find(vector::iterator beg, vector::iterator end, int val);
int main() {
vector a{ 1, 2, 3, 4, 5 };
bool result = Find(a.begin(), a.end(), 1);
if (result)
cout << "True";
else
cout << "False";
return 0;
}
bool Find(vector::iterator beg, vector::iterator end, int val) {
while (beg != end) {
if (val == *beg) {
return true;
}
beg++;
}
return false;
}
#include
#include
#include
#include
using namespace std;
vector::iterator Find(vector::iterator beg, vector::iterator end, int val);
int main() {
vector a{ 1, 2, 3, 4, 5 };
vector::iterator result = Find(a.begin(), a.end(), 9);
if (result == a.end()) {
cout << "False";
}
else
cout << "True";
return 0;
}
vector::iterator Find(vector::iterator beg, vector::iterator end, int val) {
while (beg != end) {
if (val == *beg) {
return beg;
}
beg++;
}
return end;
}
错误的地方在于.
没有理解这几种容器的结构特点
list容器是不支持 <运算的
list 容器只支持 递增,递减 == 和 != 运算.
vector::iterator
list::value_type
list::reference
cbegin() 不可以执行写操作
v1 就是普通的int vector
v2 就是常量的int vector 不能执行写操作
it1是普通的迭代器 可以执行写操作
it2,it3,it4都是const 迭代器,都不能执行写操作
vector a1;
vector a2(10);
vector a3 = a1; vector a8(a1);
vector a4{ 1,2,3,4 };vector a5 = { 1,2,3,4 };
vector a6(10, 0);
vector a7(a6.begin(), a6.begin() + 3);
vector a9(7);
前一种完整
后一种灵活
这是自己写的脑瘫方法
#include
#include
#include
#include
using namespace std;
int main(){
list a{1,2,3,4,5};
vector b;
for(auto t:a){
double x=(double)t;
b.push_back(x);
}
for(auto t:b){
cout< c{1,2,3,4,5};
vector d;
for(auto t:c){
double x=(double)t;
d.push_back(x);
}
for(auto t:d){
cout<
这是教科书上的方法
#include
#include
#include
using namespace std;
int main(){
list ilist={1,2,3,4,5,6,7};
vector ivec={7,6,5,4,3,2,1};
vector dvec(ilist.begin(),ilist.end());
vector dvecl(ivec.begin(),ivec.end());
cout<
#include
#include
#include
#include
using namespace std;
int main() {
vector a;
listb = {"I","will", "Become", "rich", "and", "Stronger", "and", "With", "abs" };
a.assign(b.begin(), b.end());
for(auto t:a){
cout<
#include
#include
#include
#include
using namespace std;
int main() {
vectora={1,2,3,4},b={2,3,4,5};
if(a>b)
cout<<"a>b";
else if(a
#include
#include
#include
#include
using namespace std;
bool i_v_equal(vector &ivec,list &ilist){
//比较list和vector元素的个数
if(ilist.size()!=ivec.size())
return false;
auto lb=ilist.cbegin(); //list首元素
auto le=ilist.cend(); //list尾元素
auto vb=ivec.cbegin(); //vector首元素
for(;lb!=le;lb++,vb++)
if(*lb!=*vb)
return false;
return true;
}
int main(){
vector ivec={1,2,3,4,5,6,7};
list ilist={1,2,3,4,5,6,7};
list ilist1={1,2,3,4,5};
list ilist2={1,2,3,4,5,6,8};
list ilist3={1,2,3,4,5,7,6};
cout<
① 容器类型必须相同,元素类型也必须相同
② 元素类型必须支持 < 运算符
#include
#include
#include
#include
#include
using namespace std;
int main(){
string a;
deque b;
while(cin>>a){
b.push_back(a);
}
deque::iterator begin=b.begin();
deque::iterator end=b.end();
while(begin!=end){
cout<<*begin<
#include
#include
#include
#include
#include
using namespace std;
int main(){
string a;
list b;
while(cin>>a){
b.push_back(a);
}
list::iterator begin=b.begin();
list::iterator end=b.end();
while(begin!=end){
cout<<*begin<
#include
#include
#include
#include
#include
using namespace std;
int main(){
int a;
list b;
while(cin>>a){
b.push_back(a);
}
list::iterator begin=b.begin();
list::iterator end=b.end();
deque even; //偶数
deque odd; //奇数
while(begin!=end){
cout<<*begin<
效果其实是一样的。
但是在vector中,只有不是push_back 就是插入到尾部,
别的插入也都是可以的.
但是速度会很慢.
① 向一个vector,string,deque插入元素.会使现有指向容器的迭代器失效.
② 其次,练习如何利用insert返回的迭代器,使得在向容器插入元素后,仍能正确的在容器中遍历.
解法一:
#include
#include
using namespace std;
int main(void){
vector iv={1,1,2,1};
int some_val=1;
vector::iterator iter=iv.begin();
int org_size=iv.size(),new_ele=0; //原大小和新元素个数
//每个循环步都重新计算 "mid",保证指向iv原中央元素
while(iter!=(iv.begin()+org_size/2+new_ele))
if(*iter==some_val){
iter=iv.insert(iter,2*some_val); //iter指向新元素
new_ele++;
iter++;iter++; //吧tier推进到旧元素的下一个位置
}else iter++; //简单推进iter
//用begin()获取vector首元素迭代器,遍历vector中的所有元素
for(iter=iv.begin();iter!=iv.end();iter++)
cout<<*iter<
解法二:
#include
#include
using namespace std;
int main(void){
vector iv={1,1,2,1};
int some_val=1;
vector::iterator iter=iv.begin();
int org_size=iv.size(),i=0; //原大小
//用循环变量控制循环次数
while(i<=org_size/2){
if(*iter==some_val){
iter=iv.insert(iter,2*some_val);
iter++;iter++;
}else iter++;
i++;
}
//用begin()获取vector首元素迭代器,遍历vector中的所有元素
for(iter=iv.begin();iter!=iv.end();iter++)
cout<<*iter<
四个值都一样,都等于容器中第一个元素的指.
#include
#include
using namespace std;
int main(void){
vector a;
cout<<*a.begin();
cout<
结果如下:
#include
#include
using namespace std;
int main(void){
vector a={1,2,3,4,5};
a.erase(a.begin(),a.begin());
for(auto i:a){
cout<
会报错!!!
具体原因没有找到,我翻了一哈,官网的代码说明,没有找到解释,
但是在我自己的环境里写了,会报错.
一样的报错.
#include
#include
#include
using namespace std;
int main(void){
int ia[]={0,1,1,2,3,5,8,13,21,55,89};
vector iv;
list il;
iv.assign(ia,ia+11);
il.assign(ia,ia+11);
vector:: iterator iiv=iv.begin();
while(iiv!=iv.end()){
if(!(*iiv&1))
iiv=iv.erase(iiv);
else iiv++;
}
list:: iterator iil=il.begin();
while(iil!=il.end()){
if(!(*iil&1))
iil=il.erase(iil);
else iil++;
}
for(auto i:iv){
cout<
#include
#include
#include
#include
using namespace std;
int main(void){
forward_list flst={0,1,2,3,4,5,6,7,8,9};
auto prev=flst.before_begin();
auto curr=flst.begin();
while(curr!=flst.end()){
if(*curr%2)
curr=flst.erase_after(prev);
else{
prev=curr;
++curr;
}
}
for(auto i:flst){
cout<
#include
#include
#include
using namespace std;
void forwar_list_insert(forward_list &, string, string);
int main(void) {
forward_list flst = { "Money","Power","Girl","Desire" };
forwar_list_insert(flst, "Power", "Wife");
//输出
for (auto i : flst) {
cout << i << " ";
}
cout << endl;
}
void forwar_list_insert(forward_list& flst, string find_string, string insert_string) {
auto curr = flst.begin();
auto prev = flst.before_begin();
while (curr != flst.end()) {
if (*curr == find_string) {
flst.insert_after(curr, insert_string);
return;
}
else {
prev = curr;
++curr;
}
}
flst.insert_after(prev, insert_string);
return;
}
会自动填充75个值,值的内容要看vec的类型
resize(10) 会删除后面的90个元素
对于元素是类类型,则单参数resize版本要求该类型必须提供一个默认构造函数
forward_list的改法
#include
#include
#include
#include
using namespace std;
int main(void) {
forward_list llist = { 0,1,2,3,4,5,6,7,8,9 };
auto iter = llist.begin();
auto iter_before = llist.before_begin();
while (iter != llist.end()) {
if (*iter % 2 == 0) {
iter=llist.erase_after(iter_before);
}
else {
llist.insert_after(iter_before, *iter);
iter_before = iter;
++iter;
}
}
for (auto i : llist) {
cout << i << " ";
}
cout << endl;
}
list的代码
#include
#include
#include
#include
using namespace std;
int main(void) {
list llist = { 0,1,2,3,4,5,6,7,8,9 };
auto iter = llist.begin();
while (iter != llist.end()) {
if (*iter % 2 == 0) {
iter=llist.erase(iter);
}
else {
iter=llist.insert(iter, *iter);
++iter;
++iter;
}
}
for (auto i : llist) {
cout << i << " ";
}
cout << endl;
}
不建议这样写,因为在表示式中调用这个变量,而且结果和中间都有的话,其实是看编译器的.这样写有很大机率出错.
插入元素会让begin()失效
如果不赋予的话,这个代码会报错.
会陷入死循环中
代码如下:
#include
#include
#include
#include
using namespace std;
int main(void) {
list llist = { 0,1,2,3,4,5,6,7,8,9 };
auto iter = llist.begin();
while (iter != llist.end()) {
if (*iter % 2 )
iter=llist.insert(iter, *iter);
++iter;
}
for (auto i : llist) {
cout << i << " ";
}
cout << endl;
}
capacity返回已经为vector分配了多大内存空间(单位是元素大小),也就是在不分配新空间的情况下,容器可以保存多少个元素,而size则返回容器当前已经保存了多少个元素
不可能的
list是链表,当有新元素加入时,会从内存空间分配一个新节点保存它,当从链表删除元素时,该节点占用的内存空间会被立即释放,因此,一个链表占用的内存空间总是与它保存的元素所需空间相等(换句话说,capacity总是等于size)
而array是固定大小数组,内存一次性分配,大小不变,不会变化.
因此他们均不需要capacity.
#include
#include
#include
#include
#include
using namespace std;
int main(void) {
vector vlist={0,1,2,3,4,5,6,7,8,9};
cout<<"size:"<
结果如下:
一开始就开辟了1024个svec的空间 有1024个string
默认初始化为空串
然后再输入若干字符串
然后再调整大小为
输入大小+输入大小的一半=输入大小的1.5倍
比384多
比768多
比1500多
比1572多
答案上的解释(我没有试过)
384
768
2048
2048
#include
#include
#include
#include
#include
using namespace std;
int main(void) {
vector vc={'H','e','l','l','o'};
string s(vc.data(),vc.size());
cout<
#include
#include
#include
#include
#include
using namespace std;
void input_string(string &s){
s.reserve(100);
char c;
while(cin>>c)
s.push_back(c);
}
int main(void) {
string s;
input_string(s);
cout<
#include
#include
#include
#include
#include
using namespace std;
void replace_string(string &s,const string &oldVal,const string &newVal){
auto l=oldVal.size();
if(!l)
return ; //要查找的字符串为空的情况
auto iter=s.begin();
while(iter<=s.end()-1){ //末尾少于oldVal长度的部分无须检查
auto iter1=iter;
auto iter2=oldVal.begin();
//s中iter开始的子串必须每个字符都与oldVal相同
while(iter2!=oldVal.end()&& *iter1==*iter2){
++iter1;
++iter2;
}
if(iter2==oldVal.end()){
iter=s.erase(iter,iter1);
if(newVal.size()){
iter2=newVal.end();
do{
iter2--;
iter=s.insert(iter,*iter2);
}while(iter2>newVal.begin());
}
iter+=newVal.size();
}else iter++;
}
}
int main(){
string s="tho thru tho!";
replace_string(s,"thru","throught");
cout<
#include
#include
#include
using namespace std;
void replace_string(string &s,const string &oldVal,const string &newVal){
int p=0;
while(p=s.find(oldVal,p)!=string::npos){
s.replace(p,oldVal.size(),newVal);
p+=newVal.size();
}
}
int main(){
string s="tho thru tho!";
replace_string(s,"thru","throught");
cout<
#include
#include
#include
using namespace std;
void name_string(string &name,const string &prefix,const string &suffix){
name.insert(name.begin(),1,' ');
name.insert(name.begin(),prefix.begin(),prefix.end());
name.append(" ");
name.append(suffix.begin(),suffix.end());
}
int main(){
string s="James Bond";
name_string(s,"Mr.","II");
cout<
#include
#include
#include
using namespace std;
void name_string(string &name,const string &prefix,const string &suffix){
name.insert(0," ");
name.insert(0,prefix);
name.insert(name.size()," ");
name.insert(name.size(),suffix);
}
int main(){
string s="James Bond";
name_string(s,"Mr.","II");
cout<
使用find_first_of
#include
#include
#include
using namespace std;
int main(){
string index="ab2c3d7R4E6";
index.find_first_of("1");
vector Num={'0','1','2','3','4','5','6','7','8','9'};
for(int i=0;i<=9;i++){
if(index.find_first_of(Num[i])!=string::npos){
cout<
使用not
#include
#include
using namespace std;
void find_not_char(string &s,const string &chars){
cout<<"在"<
会返回
string::npos
因为找不到
#include
#include
#include
using namespace std;
void find_longest_word(ifstream &in){
string s,longest_word;
int max_length=0;
while(in>>s){
if(s.find_first_of("bdfghjklpqty")!=string::npos)
continue;
cout<
整数
#include
#include
#include
#include
using namespace std;
int main(){
vector index={"1","2","3","4","5","6"};
int sum=0;
for(auto i:index){
sum+=stoi(i);
}
cout<
21
请按任意键继续. . .
浮点数
#include
#include
#include
#include
using namespace std;
int main(){
vector index={"1.90","2.85","3","4","5","6"};
double sum=0;
for(auto i:index){
sum+=stod(i);
}
cout<
22.75
请按任意键继续. .