本书为Primer C++ 中文第五版
练习题笔记
(9.1)
a>vector;无需在中间位置进行插入元素,插入后利用sort即可达到要求
b>deque;典型的队列操作,在头尾部进行插入或删除操作
c>vector;可变大小数组,可全部插入后利用sort排序输出
(9.2)
list<queue<int>> lst;
(9.3)
构成范围的迭代器的要求为
1.指向同一个容器中的元素,或者是容器最后一个元素之后的位置。
2.可以反复递增begin来到达end。
(9.4)
bool test4(vector<int>::iterator begin, const vector<int>::iterator end, int n) {
while(begin != end) {
if(*begin == n) return true;
begin++;
}
return false;
}
(9.5)
vector<int>::iterator test4(vector<int>::iterator begin, const vector<int>::iterator end, int n) {
while(begin != end) {
if(*begin == n) return begin;
begin++;
}
return begin;
}
(9.6)
list没有定义'<'操作符,需要改成 while(iter1 != iter2)
(9.7)
vector<int>::iterator iter;
(9.8)
string 或者 list<string>::value_type
string 或者 list<string>::referebce
(9.9)
begin()和cbegin()的区别在于定义迭代器是否为常量
cbegin()是C++新标准引入的,与auto一起使用可以隐式的选择迭代器类型
当容器为常量时,使用begin()和cbegin()迭代器都是常量
当容器为非常量时,使用begin()迭代器是非常量,使用cbegin()迭代器是常量
(9.10)
it1 非常量
it2 常量
it3 常量
it4 常量
(9.11)
vector<int> vec;
1.vector<int> vec1;
2.vector<int> vec2(vec);
3.vector<int> vec3 = {0, 1, 2, 3};
4.vector<int> vec4(vec.begin(), vec.end());
5.vector<int> vec5(10);
6.vector<int> vec6(10,1);
(9.12)
元素个数不同,拷贝是全部,迭代器是部分(也可能是全部,begin()->end())
(9.13)
list<int> lst = {0, 1, 2, 3, 4};
vector<int> ive = {4, 3, 2, 1, 0};
vector<double> dve(lst.begin(), lst.end());
vector<double> dve2(ive.begin(), ive.end());
(9.14)
list<char*> lst = {"a", "aa", "aaa"};
vector<string> sve(lst.begin(), lst.end());
(9.15)
bool test15(vector<int> ive1, vector<int> ive2) {
auto bive1 = ive1.cbegin();
auto bive2 = ive2.cbegin();
while(bive1 != ive1.cend() && bive2 != ive2.cend()) {
if(*bive1 != *bive2) return false;
bive1++;
bive2++;
}
if(bive1 == ive1.cend() && bive2 == ive2.cend()) return true;
else return false;
}
(9.16)
bool test15(list<int> ilst, vector<int> ive) {
auto bilst = ilst.cbegin();
auto bive = ive.cbegin();
while(bilst != ilst.cend() && bive != ive.cend()) {
if(*bilst != *bive) return false;
bilst++;
bive++;
}
if(bilst == ilst.cend() && bive == ive.cend()) return true;
else return false;
}
(9.17)
三个条件
1.容器类型相同
2.容器内的元素类型相同
3.容器支持运算符'<'
(9.18)
string s;
deque<string> ds;
while(cin >> s && s != "q") {
ds.push_back(s);
}
(9.19)
string s;
list<string> ls;
while(cin >> s && s != "q") {
ls.push_back(s);
}
(9.20)
list<int> lst = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
cout << "全部数:" << endl;
for(auto d : lst) cout << d << " ";
cout << endl;
deque<int> d1, d2;
auto begin = lst.cbegin();
while(begin != lst.cend()) {
if(*begin % 2 == 0) d1.push_back(*begin);
else d2.push_back(*begin);
begin++;
}
cout << "偶数:" << endl;
for(auto d : d1) cout << d << " ";
cout << endl;
cout << "奇数:" << endl;
for(auto d : d2) cout << d << " ";
cout << endl;
(9.21)
vector<string> vec;
auto iter = vec.begin();
while(cin >> word) iter = vec.insert(iter, word);
首先定义iter为vec的begin
然后用insert函数在容器begin前插入word
最后函数返回指向插入元素的迭代器,也就是插入元素后容器的begin位置
(9.22)
对于vector,在用完insert函数之后,之前的迭代器都会失去效果
也就是在使用insert函数后,iter 和 mid 都会失效,需要重新赋值
修改为
vector<int>::iterator iter = iv.begin();
int new_ele = 0;
while(iter != iv.begin + iv.size() / 2 + new_ele) {
if(*iter == some_val) {
iter = iv.insert(iter, 2 * some_val);
iter += 2;
new_ele++;
}
else iter++;
}
(9.23)
val1, val2, val3, val4四个值都是c中唯一的一个数
(9.24)
如过vector为空,则会报错
(9.25)
范围删除是一个左闭右开的区间,返回右边的迭代器
当elem1 == elem2,需要返回elem2,所以不执行删除
当elem2 == 尾后迭代器,则删除包括elem1在内的后面所有元素,结束后elem1 == elem2 == 尾后迭代器
当elem1 == elem2 == 尾后迭代器,不执行删除
(9.26)
int ia[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89};
vector<int> ivec;
ivec.assign(ia, ia + 11);
list<int> ilst;
ilst.assign(ia, ia + 11);
auto vbegin = ivec.begin();
auto lbegin = ilst.begin();
for(int i = 0; i < 11; i++) {
if(*vbegin % 2 == 0) {
vbegin = ivec.erase(vbegin);
}else {
vbegin++;
}
if(*lbegin % 2 == 1) {
lbegin = ilst.erase(lbegin);
}else {
lbegin++;
}
}
(9.27)
forward_list<int> flst = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
auto prev = flst.before_begin();
auto begin = flst.begin();
while(begin != flst.end()) {
if(*begin % 2) {
begin = flst.erase_after(prev);
}else {
prev = begin++;
}
}
(9.28)
void Inser(forward_list<string> &flst, string ser, string in) {
auto prev = flst.before_begin();
auto begin = flst.begin();
while(begin != flst.end()) {
if(*begin == ser) {
flst.insert_after(begin,in);
return;
}
prev = begin++;
}
flst.insert_after(prev, in);
return;
}
void test28() {
forward_list<string> flst = {"I", "am", "ITer"};
string ser, in;
cin >> ser >> in;
Inser(flst, ser, in);
for(auto s : flst) cout << s << " ";
cout << endl;
cin >> ser >> in;
Inser(flst, ser, in);
for(auto s : flst) cout << s << " ";
cout << endl;
}
(9.29)
vec.resize(100) -> 初始化75个元素插入到vec中
vec.resize(10) -> 从vec末尾删除90个元素
(9.30)
元素有默认初始值
(9.31)
list 和 forward_list 没有'+'操作,需要用'++';
forward_list 需要用 erase_after 和 insert_after;
(9.32)
不合法。对实参求值、向形参传递的处理顺序,不同的编译器可能不同
(9.33)
begin迭代器将会失效,程序可能会出现错误
(9.34)
迭代器少加了一次,当出现奇数值时,会一直循环
需要再加上一行 ++iter;
(9.35)
capacity 当前容器在不重新分配内存的情况下最多能有多少个元素
size 当前容器的元素个数
capacity >= size
(9.36)
不可能
(9.37)
list 存储的元素间不是连续地址,可以随便的增删
array 在定义的时候就已经固定数量了
(9.38)
vector<int> vec;
vec.reserve(10);
cout << vec.size() << " " << vec.capacity() << endl;
while(vec.size() != vec.capacity()) {
vec.push_back(1);
}
cout << vec.size() << " " << vec.capacity() << endl;
vec.push_back(1);
cout << vec.size() << " " << vec.capacity() << endl;
结果为:
0 10
10 10
11 20
(9.39)
第一行 定义了一个string的vector容器
第二行 给这个容器预留了1024个string内存空间
第三行到第五行 输入string存储到容器中
最后一行 在容器尾部添加当前容器数量的一半个空字符串
(9.40)
if 256 then capacity 1024
if 512 then capacity 1024
if 1000 then capacity 2048
if 1048 then capacity 2048
(9.41)
vector<char> vec = {'s', 't', 'r', 'i', 'n', 'g'};
string s;
for(auto c : vec) s += c;
(9.42)
可以提前给string分配空间
(9.43)
void Rep(string &s, string oldVal, string newVal) {
auto begin = s.begin();
while(begin != s.end()) {
if(*begin == oldVal[0] ) {
string tmp(begin, begin + oldVal.size());
if(tmp == oldVal) {
begin = s.insert(begin, newVal.begin(), newVal.end());
begin += newVal.size();
s.erase(begin, begin + oldVal.size());
}
else begin++;
}
else begin++;
}
}
(9.44)
void Rep2(string &s, string oldVal, string newVal) {
auto begin = s.begin();
while(begin != s.end()) {
if(*begin == oldVal[0] ) {
string tmp(begin, begin + oldVal.size());
if(tmp == oldVal) {
s.replace(begin, begin + oldVal.size(), newVal);
begin += newVal.size();
}
else begin++;
}
else begin++;
}
}
(9.45)
void Add(string &name, string pre, string nex) {
auto begin = name.begin();
name.insert(begin, pre.begin(), pre.end());
name.append(nex);
}
(9.46)
void Add2(string &name, string pre, string nex) {
name.insert(name.size(), nex);
name.insert(0, pre);
}
(9.47)
string s = "ab2c3d7R4E6";
string num = "0123456789";
cout << s << endl;
auto pos = s.find_first_of(num);
do{
cout << s[pos] << " ";
pos++;
pos = s.find_first_of(num, pos);
}while(pos != string::npos);
cout << endl;
auto p = s.find_first_not_of(num);
do{
cout << s[p] << " ";
p++;
p = s.find_first_not_of(num, p);
}while(p != string::npos);
cout << endl;
(9.48)
npos
(9.49)
void test49() {
fstream fin;
fin.open("test.txt");
string de("bdfghjklpqtyBDFGHJKLPQTY");
int lengthmax = 0;
string ret;
if(fin) {
string word;
while(fin >> word) {
auto pos = word.find_first_of(de);
if(pos == string::npos && lengthmax < word.size()) {
lengthmax = word.size();
ret = word;
}
}
}
fin.close();
cout << lengthmax << " " << ret << endl;
return;
}
(9.50)
void test50() {
vector<string> svec = {"1", "12", "3", "5"};
float sum = 0;
for(auto s : svec) sum += stof(s);
cout << sum << endl;
}
(9.51)
map<string,unsigned int> M = {
{"January", 1}, {"Jan", 1}, {"1", 1},
{"February",2}, {"Feb", 2}, {"2", 2},
{"March", 3}, {"Mar", 3}, {"3", 3},
{"April", 4}, {"Apr", 4}, {"4", 4},
{"May", 5}, {"5", 5},
{"June", 6}, {"Jun", 6}, {"6", 6},
{"July", 7}, {"Jul", 7}, {"7", 7},
{"August", 8}, {"Aug", 8}, {"8", 8},
{"September", 9}, {"Sept", 9}, {"9", 9},
{"October", 10}, {"Oct", 10}, {"10", 10},
{"November", 11}, {"Nov", 11}, {"11", 11},
{"December", 12}, {"Dec", 12}, {"12", 12}
};
struct Date {
unsigned int year, month, day;
Date(string date) {
string m = date.substr(0, date.find_first_of(" ,/"));
string y = date.substr(date.find_first_of(",/ "));
y.erase(y.begin());
string d = y.substr(0, y.find_first_of(" ,/"));
y = y.substr(y.find_first_of(" ,/"));
y.erase(y.begin());
cout << y << " " << m << " " << d << endl;
year = stof(y);
day = stof(d);
if(M.count(m)) {
month = M[m];
}else month = 0;
cout << year << " " << month << " " << day << endl;
}
};
(9.52)
#include <iostream>
#include <stack>
#include <string>
using namespace std;
bool lower(string l, string h) {
if((h == "*" || h == "/") && (l == "+" || l == "-")) {
return true;
}
else if(l == "*" && h == "/") {
return true;
}
else if(l == "+" && h == "-") {
return true;
}
else return false;
}
void calcu(stack<int> &v, stack<string> &o) {
int tmp1 = v.top();
v.pop();
int tmp2 = v.top();
v.pop();
int tmp;
string ope = o.top();
o.pop();
if(ope == "+") {
tmp = tmp1 + tmp2;
}else if(ope == "-") {
tmp = tmp2 - tmp1;
}else if(ope == "*") {
tmp = tmp1 * tmp2;
}else if(ope == "/") {
tmp = tmp2 / tmp1;
}
v.push(tmp);
}
void cal(string s) {
auto begin = s.begin();
stack<string> o;
stack<int> v;
while(s.size() != 0) {
string ele = s.substr(0, s.find_first_of("+-*/()="));
s = s.substr(s.find_first_of("+-*/()="));
string ope = s.substr(0, 1);
s.erase(s.begin());
//操作数入栈
if(ele.size() != 0) {
v.push(stoi(ele));
}
//操作符入栈
if(ope.size() != 0 && ope != "=") {
if(!o.empty() && lower(ope, o.top())) {
calcu(v, o);
}
if(ope == ")") {
string l = o.top();
while(l != "(") {
calcu(v, o);
l = o.top();
}
o.pop();
}
else {
o.push(ope);
}
}
}
while(!o.empty()) {
calcu(v, o);
}
cout << v.top() << endl;
}
int main() {
string s;
while(getline(cin, s) && s != "q") {
if(*s.end() != '=') s.append("=");
cal(s);
}
return 0;
}