书籍版本:2019年9月第一版;王刚 杨巨峰译;电子工业出版社
编译器 : win10 && VS2015
9.1
a. list因为可能会在容器中间插入元素
b.deque因为只在容器头尾操作
c. vector因为是未知数量,还需要排序
9.2
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <deque>
using namespace std;
int main(int argc, char** argv)
{
typedef deque<int> INT_DEQUE;
list<INT_DEQUE> int_deque_list;
system("pause");
return 0;
}
9.3
他们必须指向同一个容器中的元素或是容器中最后一个元素之后的位置,并且可以通过对一个迭代器的反复递增到达另一个迭代器。
9.4
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <deque>
using namespace std;
int main(int argc, char** argv)
{
int nFind = 9; // 需要寻找的数
vector<int> intVec = { 0,1,2,3,4,5,6,9,8,7 };
bool bFind = false; //标记是否找到
vector<int>::iterator begin = intVec.begin();
vector<int>::iterator end = intVec.end();
while (begin != end)
{
if (*begin == nFind)
{
bFind = true;
break;
}
++begin;
}
if (bFind)
{
cout << "找到啦" << endl;
}
else
{
cout << "没找到" << endl;
}
system("pause");
return 0;
}
9.5
vector<int>::iterator FindByIter(vector<int> intVec, int nFind)
{
vector<int>::iterator begin = intVec.begin();
vector<int>::iterator end = intVec.end();
while (begin != end)
{
if (*begin == nFind)
{
break;
}
++begin;
}
return begin;// 找到的话返回的是对应值的迭代器,没找到会一直++到end
}
9.6
迭代器没办法比较大小,只能比较迭代器中指向的值的大小。
9.7
vector<int>::size_type ;
9.8
list<string>::iterator || list<string>::const_iterator ; 读时两种都可以
list<string>::iterator;写时不能用const
9.9
cbegin()返回的是const i迭代器
begin()返回的是普通迭代器
9.10
vector<int> v1; // 里面装着int的vector;
const vector<int> v2; // 里面装着int的vector;
auto it1 = v1.begin();, it2 = v2.begin;//it1与it2都是vector<int>的迭代器
auto it3 = v1.cbegin(), it4 = v2.cbegin(); //it3与it4是vector<int>的常量迭代器
9.11
vector<int> vec1; //默认初始化
vector<int> vec2 = {1, 2, 3}; //列表初始化,含有3个int类型的元素
vector<int> vec3(vec2); //拷贝初始化,拷贝v2,含有3个intl类型的元素
vector<int> vec4(10); //特定构造函数定义的初始化,含有10个元素
vector<int> vec5(10, 5); //特定构造函数定义的初始化,含有10个元素,元素值初始化为5
vector<int> vec6(vector<int>::iterator begin, vector<int>::iterator end); //特定构造函数定义的初始化,含有从begin到end的之间的所有元素,元素值对应迭代器范围的元素值
9.12
接收一个容器创建其拷贝的两个容器必须是相同类型,且其中元素也必须为相同类型;
接收两个迭代器创建拷贝时只要求元素相容。
9.13
// 拷贝list
list<int> lst1 = {1,2,3};
list<int>::iterator begin = lst1.begin();
list<int>::iterator end = lst1.end();
vector<double> vecDouble(begin, end);
// 拷贝vector
vector<int> vec1 = { 4,5,6 };
vector<int>::iterator vBegin = vec1.begin(), vEnd = vec1.end();
vector<double> vecDs(vBegin, vEnd);
9.14
list<char *> lst1 = {"hello","world"};
vector<string> strVec;
strVec.assign(lst1.begin(), lst1.end());
9.15
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char** argv)
{
vector<int> vec1 = { 1 };
vector<int> vec2 = { 12 };
if (vec1 == vec2)
{
cout << "相等" << endl;
}
else
{
cout << "不相等" << endl;
}
system("pause");
return 0;
}
9.16
9.17
关系运算符左右两边的运算对象必须是相同类型的容器,且必须保存相同类型的元素。
9.18
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <deque>
using namespace std;
int main(int argc, char** argv)
{
deque<string> sDeque;
string s;
while (cin >> s)
{
sDeque.push_back(s);
}
for (deque<string>::iterator iter = sDeque.begin();
iter!= sDeque.end();
++iter)
{
cout << *iter << endl;
}
system("pause");
return 0;
}
9.19
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <deque>
using namespace std;
int main(int argc, char** argv)
{
list<string> sList;
string s;
while (cin >> s)
{
sList.push_back(s);
}
for (list<string>::iterator iter = sList.begin();
iter!= sList.end();
++iter)
{
cout << *iter << endl;
}
system("pause");
return 0;
}
9.20
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <deque>
using namespace std;
int main(int argc, char** argv)
{
list<int> nList = {1,2,3,4,5,6,7,8,9};
deque<int> oldVec, evenVec;
for (list<int>::iterator iter = nList.begin();
iter != nList.end();
++iter)
{
if (*iter %2 == 0)
{
evenVec.push_back(*iter);
}
else if(*iter % 2 == 1)
{
oldVec.push_back(*iter);
}
}
system("pause");
return 0;
}
9.21
操作与list无区别
9.22
首先要注意:迭代器加上固定的数字指的是迭代器的增长,而不是数值的增长,此处加上iv.size()/2取得的就是vector 的中间元素值。
题目中的程序原意应是在vector的前半部分中查找是否存在与some_value相等的值,如果存在,则在对应元素前面插入一个2*some_value,问题是一次插入之后mid就失效了;另外,每次比较之后iter位置都没有改变。
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <deque>
using namespace std;
int main(int argc, char** argv)
{
vector<int> iv = { 1,2,3,4,555,6,7,8,9 };
vector<int>::iterator iter = iv.begin(), mid = iv.begin() + iv.size() / 2;
int some_value = 5;
while (iter != mid)
{
if (*iter == some_value)
{
iter = iv.insert(iter, 2 * some_value);
mid = iv.begin() + iv.size() / 2 + 1;// 每次插入一个元素后mid都要再向后移动一位
iter += 2;//iter由指向新插入的元素再向后移动两位
}
else
{
++iter;
}
}
system("pause");
return 0;
}
9.23
size为1即为只有一个元素,那么四个值都为第一个元素值
9.24
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <deque>
using namespace std;
int main(int argc, char** argv)
{
vector<int> iv = { 1,2,3,4,555,6,7,8,9 };
int a = iv.at(0);
int b = iv[0];
int c = iv.front();
vector<int>::iterator iter = iv.begin();
int d = *iter;
system("pause");
return 0;
}
当vector为空时运行会报错
9.25
如果elem1和elem2相等,则范围为0不会删除任何元素;
如果elem2是尾后迭代器,那么从elem1之后的元素都会被删除;
如果两者皆为尾后迭代器,则范围为0不进行任何删除;
9.26
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <deque>
using namespace std;
int main(int argc, char** argv)
{
int ia[] = { 0,1,2,3,5,8,13,21,55,89 };
vector<int> nVec;
list<int> nList;
for (int i = 0; i < 11; i++)
{
nVec.push_back(ia[i]);
nList.push_back(ia[i]);
}
for (vector<int>::iterator iter = nVec.begin();
iter != nVec.end();
++iter)
{
if (*iter &2 == 0)
{
nVec.erase(iter);
}
}
for (list<int>::iterator iter = nList.begin();
iter != nList.end();
++iter)
{
if (*iter & 2 == 0)
{
nList.erase(iter);
}
}
system("pause");
return 0;
}
9.27
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;
int main(int argc, char** argv)
{
forward_list<int> fwList = { 1,2,3,4,5,6,7,8,9 };
auto prev = fwList.begin();
auto curr = fwList.begin();
while (curr != fwList.end())
{
if ( *curr %2)
{
curr = fwList.erase_after(prev);
}
else
{
prev = curr;
++curr;
}
}
auto iter = fwList.begin();
while (iter != fwList.end())
{
cout << *iter << endl;
++iter;
}
system("pause");
return 0;
}
9.28
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;
void FListFunc(forward_list<string>& strList, const string str1, const string str2)
{
auto last = strList.begin();
auto iter = strList.begin();
while (iter != strList.end())
{
if ((*iter) == str1)
{
strList.insert_after(iter, str2);
return;
}
else
{
last = iter;
++iter;
}
}
strList.insert_after(last, str2);
}
int main(int argc, char** argv)
{
forward_list<string> strList = { "hello", "world" };
FListFunc(strList, "yingyingying", "!");
auto begin = strList.begin();
while (begin != strList.end())
{
cout << *begin;
++begin;
}
system("pause");
return 0;
}
9.29
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;
int main(int argc, char** argv)
{
forward_list<int> nList(25, 1);
nList.resize(100);
auto iter = nList.begin();
while (iter != nList.end())
{
cout << *iter << " ";
++iter;
}
cout << endl;
cout << "我是一道快乐的分割线**********" << endl;
nList.resize(10);
auto iter1 = nList.begin();
while (iter1 != nList.end())
{
cout << *iter1 << " ";
++iter1;
}
system("pause");
return 0;
}
第一次resize(100)时因为没有指定要添加的值,会添加75个默认的值;
然后resize(10)时,会将之前的100个元素的后90个删除;
9.30
元素必须具有默认构造函数
9.31
list与forword_list都不支持 iter+=2 操作;forword_list 不可以使用insert与erase;
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;
int main(int argc, char** argv)
{
//vector<int> vi = { 0,1,2,3,4,5,6,7,8,9 };
list<int> vi = { 0,1,2,3,4,5,6,7,8,9 };
auto iter = vi.begin();
while (iter != vi.end())
{
if (*iter % 2)
{
iter = vi.insert(iter, *iter);
++iter;
++iter;
}
else
{
iter = vi.erase(iter);
}
}
//forward_list<int> vi = { 0,1,2,3,4,5,6,7,8,9 };
//auto iter = vi.begin();
//auto last = vi.begin();
//while (iter != vi.end())
//{
// if (*iter % 2)
// {
// ++iter;
// iter = vi.insert_after(iter, *iter);
// ++iter;
// }
// else
// {
// iter = vi.erase_after(last);
// }
// last = iter;
//}
system("pause");
return 0;
}
9.32
不行,编译器不会提示错误,但运行时会出问题;原因是参数的求值顺序是未指定,无法保证括号内的计算顺序。
9.33
在begin = v.insert(begin, 42);时,begin会指向刚刚插入的42,
如果不将insert的结果赋给begin,那么begin将会失效;
9.34
这段程序原本应该是想遇到奇数就在容器中插入一个同样值的奇数;但是这样写导致第一次insert之后iter就指向了新插入的那个值,由于新插入的值还是之前那个奇数,导致之后每次循环都会插入这个奇数,永远不会结束
9.35
size是指容器已经保存的元素个数;可以将size理解为已使用的空间大小;
capacity是在不分配新的内存空间的前提下容器最多可以保存多少元素;可以将capacity理解为当前已开辟的空间大小
9.36
不可能,capacity一定大于等于size;
9.37
因为list是链表,不需要事先分配内存;而array不允许改变容器大小
9.38
略。。。。。
9.39
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char** argv)
{
vector<string> sVec;
sVec.reserve(1024);//为sVec申请大小为1024的空间
string word;
while (cin >> word)// 将输入的string存入sVec中
{
sVec.push_back(word);
}
sVec.resize(sVec.size() + sVec.size() / 2);//将sVec的大小变为之前的1.5倍;此时sVec的大小不一定为1024
system("pause");
return 0;
}
9.40
如果读入了256歌词,resize之后的代销可能为1024*1.5 = 1536;
读入512个时,可能为1024*1.5 = 1536;
读入512个时,可能为1024*1.5 = 1536;
读入1000个时,可能为1024*1.5 = 1536;
读入1048个时,可能为1024*2*1.5 = 3072;
(默认每次重新申请空间按两倍申请,具体实现时可能不一定为2倍)
9.41
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char** argv)
{
vector<char> chVec;
chVec.push_back('h');
chVec.push_back('e');
chVec.push_back('l');
chVec.push_back('l');
chVec.push_back('o');
string s(chVec.begin(), chVec.end());
cout << s << endl;
system("pause");
return 0;
}
9.42
使用reserve预先为其分配好空间
9.43
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void strFunc(string& s,const string oldVal,const string newVal)
{
int nSSize = s.length();
int nOldLen = oldVal.length();
if (nSSize <= 0 || nSSize < nOldLen)
{
return;
}
auto iters = s.begin();
while (iters != s.end())
{
string str = s.substr(iters - s.begin(), nOldLen);
if (str == oldVal)
{
s.erase(iters, iters + nOldLen);
for (auto iterss = newVal.begin(); iterss != newVal.end(); iterss++)
{
s.insert(iters, *iterss);
iters++;
}
}
else
{
iters++;
}
}
}
int main(int argc, char** argv)
{
string s("ingthohdufb");
cout << "执行前" << s << endl;
strFunc(s, "tho", "through");
cout << "执行后" << s << endl;
system("pause");
return 0;
}
9.44
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void strFunc(string& s,const string oldVal,const string newVal)
{
int nSSize = s.length();
int nOldLen = oldVal.length();
if (nSSize <= 0 || nSSize < nOldLen)
{
return;
}
auto iters = s.begin();
while (iters != s.end())
{
string str = s.substr(iters - s.begin(), nOldLen);
if (str == oldVal)
{
s.erase(iters, iters + nOldLen);
for (auto iterss = newVal.begin(); iterss != newVal.end(); iterss++)
{
s.insert(iters, *iterss);
iters++;
}
}
else
{
iters++;
}
}
}
void strFuncTwo(string& s, const string oldVal, const string newVal)
{
int nSSize = s.length();
int nOldLen = oldVal.length();
if (nSSize <= 0 || nSSize < nOldLen)
{
return;
}
for (int i = 0; i < nSSize; i++)
{
string str = s.substr(i, nOldLen);
if (str == oldVal)
{
s.replace(i, nOldLen, newVal);
i = i + nOldLen;
}
}
}
int main(int argc, char** argv)
{
string s("ingthohdufb");
cout << "执行前" << s << endl;
//strFunc(s, "tho", "through");
strFuncTwo(s, "tho", "through");
cout << "执行后" << s << endl;
system("pause");
return 0;
}
9.45
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
string AddStringByIter(string name, const string prop, const string suff)
{
if (name.empty() )
{
return name;
}
if (!prop.empty())
{
name.insert(name.begin(), prop.begin(), prop.end());
}
if (!suff.empty())
{
name.append(suff);
}
return name;
}
int main(int argc, char** argv)
{
string s("Tom");
cout << "执行前" << s << endl;
s = AddStringByIter(s, "Mr.", "Ⅲ");
cout << "执行后" << s << endl;
system("pause");
return 0;
}
9.46
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
string AddStringByIter(string name, const string prop, const string suff)
{
if (name.empty() )
{
return name;
}
if (!prop.empty())
{
name.insert(0, prop);
}
if (!suff.empty())
{
name.insert(name.size(), suff);
}
return name;
}
int main(int argc, char** argv)
{
string s("Tom");
cout << "执行前" << s << endl;
s = AddStringByIter(s, "Mr.", "Ⅲ");
cout << "执行后" << s << endl;
system("pause");
return 0;
}
9.47
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;
int main(int argc, char** argv)
{
string str = "ab2c3d7R4E6";
string num = "0123456789";
string alpha = "abcdeghijklmnopqrstuvwxyz";
/*find_first_of版*/
for (auto iter = num.begin(); iter != num.end(); iter++)
{
auto pos = str.find_first_of(*iter);
if (pos != string::npos)
{
cout << "找到了:" << *iter << endl;
}
}
cout << "****************************" << endl;
for (auto iter = alpha.begin(); iter != alpha.end(); iter++)
{
auto pos = str.find_first_of(*iter);
if (pos != string::npos)
{
cout << "找到了:" << *iter << endl;
}
}
cout << "****************************" << endl;
/*find_first_not_of版*/
auto pos = 0;
for (auto iter = num.begin(); iter != num.end(); iter++)
{
for (int i = 0; i < str.size(); i++)
{
auto pos2 = str.find_first_not_of(*iter, i);
if (pos2 != i && pos2 != string::npos)
{
cout << "找到了:" << str[pos2 - 1] << endl;
}
}
}
cout << "****************************" << endl;
pos = 0;
for (auto iter = alpha.begin(); iter != alpha.end(); iter++)
{
for (int i = 0; i < str.size(); i++)
{
auto pos2 = str.find_first_not_of(*iter, i);
if (pos2 != i && pos2 != string::npos)
{
cout << "找到了:" << str[pos2 - 1] << endl;
}
}
}
system("pause");
return 0;
}
9.48
numbers里面没有name的第一个字符,所以返回string::npos
9.49
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;
int main(int argc, char** argv)
{
string str = "teststr";
string evail = "bdfhkltgjpqy";
vector<string> strVec;
bool bBegin = false;
int nBeginPos = 0, nEndPos = 0;//
int nLength = 0;
for (int i = 0; i < str.size(); i++)
{
auto pos = evail.find_first_of(str[i]);
if ( pos != string::npos )
{
if (bBegin)
{
string strs = str.substr(nBeginPos, nLength);
strVec.push_back(strs);
nBeginPos = 0;
nEndPos = 0;
nLength = 0;
bBegin = false;
}
continue;
}
else
{
nLength++;
if (!bBegin)
{
nBeginPos = i;
nEndPos = i + 1;
bBegin = true;
}
else
{
nEndPos = i;
}
}
}
int strpos = 0;
int nSize = strVec.at(0).size();
for (int i = 0; i < strVec.size(); i++)
{
string s = strVec.at(i);
if (s.size() > nSize)
{
nSize = s.size();
strpos = i;
}
}
string ss = strVec.at(strpos);
cout << ss << endl;
system("pause");
return 0;
}
9.50
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char** argv)
{
vector<string> strVec = { "1","2","3","4","5" };
int sum = 0;
for (auto i = strVec.begin(); i != strVec.end(); i++)
{
int a = stoi(*i);
sum = sum + a;
}
cout << "和为:" << sum << endl;
float fSum = 0.0f;
for (auto i = strVec.begin(); i != strVec.end(); i++)
{
float a = stof(*i);
fSum = fSum + a;
}
cout << "和为:" << fSum << endl;
system("pause");
return 0;
}
9.51
懒得写了在网上炒了一份过来。。。。
#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<forward_list>
using namespace std;
class Date
{
public://class默认是私有继承,记得要加public
unsigned _year;
unsigned _month;
unsigned _day;
void _show()
{
cout<<_year<<"年"<<_month<<"月"<<_day<<"日"<<endl;
}
//构造函数
Date(string);
};
Date::Date(string s)
{
int flag = 0;
string number = "0123456789/";
string coma = ",";
string month;
unsigned pos,pos1,pos2,pos3;
unsigned _pos,_pos1;
/*利用一个判断,现判定怎样初始化*/
if ((pos = s.find_first_not_of(number)) == string::npos)
{
flag = 1;
}
if ((pos = s.find_first_of(coma)) != string::npos)
{
flag = 2;
}
switch (flag)
{
case 1:/*处理1/1/1991的格式*/
pos1 = 0;
pos1 = s.find_first_of("/",pos1);
_day = stoul(s.substr(0,pos1));//先截取目标字符串,再将字符串转化为unsigned
pos2 = ++pos1;
pos1 = s.find_first_of("/",pos1);
_month = stoul(s.substr(pos2,pos1));
pos3 = ++pos1;
_year = stoul(s.substr(pos3,s.size()-1));
break;
case 2:/*处理January 1,1900的格式*/
_pos;
_pos = s.find_first_of(number);
month = s.substr(0,_pos);
//本来想用switch,表达式的结果的类型可以是 整数类型,枚举类型,或者类类型
//(但该类需要有单一的转换到整数类型或(可以是字符类型,但不能是浮点类型、字符串、指针类型等)
if (month == "January ") _month = 1;
if (month == "February ") _month = 2;
if (month == "March ") _month = 3;
if (month == "April ") _month = 4;
if (month == "May ") _month = 5;
if (month == "June ") _month = 6;
if (month == "July ") _month = 7;
if (month == "August ") _month = 8;
if (month == "September ") _month = 9;
if (month == "October ") _month = 10;
if (month == "November ") _month = 11;
if (month == "December ") _month = 12;
_pos1 = ++_pos;
_pos = s.find_first_of(number,_pos);
_day = stoul(s.substr(_pos1-1,_pos));
_year = stoul(s.substr(_pos,s.size()-1));
break;
case 0:/*处理Jan 1 1995的格式*/
_pos;
_pos = s.find_first_of(number);
month = s.substr(0,_pos);
if (month == "Jan ") _month = 1;
if (month == "Feb ") _month = 2;
if (month == "Mar ") _month = 3;
if (month == "Apr ") _month = 4;
if (month == "May ") _month = 5;
if (month == "Jun ") _month = 6;
if (month == "Jul ") _month = 7;
if (month == "Aug ") _month = 8;
if (month == "Sep ") _month = 9;
if (month == "Oct ") _month = 10;
if (month == "Nov ") _month = 11;
if (month == "Dec ") _month = 12;
_pos1 = ++_pos;
_pos = s.find_first_of(number,_pos);
_day = stoul(s.substr(_pos1-1,_pos));
_year = stoul(s.substr(_pos,s.size()-1));
break;
}
}
int main(int argc, char**argv)
{
Date _today("25/2/2017");
_today._show();
Date _tomorrow("January 1,1995");
_tomorrow._show();
Date _2tomorrow("Jan 1 1995");
_2tomorrow._show();
return 0;
}
9.52