练习9.1(a) 使用vector+sort 或 sort
(b) deque (c) vector+sort 大量小型数据
练习9.2 list<deque<int>> x;
练习9.3 需要有两个指向同一容器的迭代器。begin不在end后面。
练习9.4
bool findX(vector<int>::iterator begin, vector<int>::iterator end, int x) {
while (begin != end) {
if (*begin == x)
return true;
begin++;
}
return false;
}
练习9.5
vector<int>::iterator findX(vector<int>::iterator begin, vector<int>::iterator end, int x) {
while (begin != end) {
if (*begin == x)
return begin;
begin++;
}
return end;
}
练习9.6 list的迭代器不支持<操作,改为!=。
练习9.7 vector<int>::value_type
练习9.8 list<string>::value_type list<string>::reference
练习9.9 begin经过重载,对const类型返回const,非const返回非const。 cbegin总是返回常量迭代器。
练习9.10 普通类型 const const const
练习9.11 vector<int> a; vector<int> a(b); vector<int> a={1,2,3,4,5};
vector<int> a = b; vector<int> a = {1,2,3,4,5}; vector<int> a(b.begin(), b.end());
练习9.12 接受一个容器则两个容器需要类型完全相同,接收两个迭代器的只需要元素类型相容。
练习9.13 vector<double> b(l.begin(), l.end()); vector<double> b(a.begin(), a.end());
练习9.14
list<const char*> l{"123", "456"};
vector<string> vs(l.begin(), l.end());
for(auto x : vs)
cout << x << endl;
return 0;
练习9.15
bool vEqual(const vector<int>& v1, const vector<int>& v2) {
if (v1.size() != v2.size())
return false;
for (int i = 0; i < v1.size(); i++)
if (v1[i] != v2[i])
return false;
return true;
}
练习9.16
bool lvEqual(const list<int> &l, const vector<int>&v) {
auto lIter = l.begin();
auto vIter = v.begin();
while (lIter != l.end() && vIter != v.end() && *lIter == *vIter) {
lIter++;
vIter++;
}
return lIter == l.end() && vIter == v.end();
}
练习9.17 c1和c2类型相同且包含的元素有<操作。
练习9.18
void inputAndPrint() {
deque<string> d;
string s;
while (cin >> s)
d.push_back(s);
deque<string>::iterator diter = d.begin();
while (diter != d.end())
cout << *diter++ << endl;
}
练习9.19
void inputAndPrintList() {
list<string> d;
string s;
while (cin >> s) {
d.push_back(s);
d.insert(d.end(), s);
d.emplace(d.end(), s);
}
list<string>::iterator diter = d.begin();
while (diter != d.end())
cout << *diter++ << endl;
}
练习9.20
void copyFromList(list<int>& l) {
list<int>::iterator iter = l.begin();
deque<int> dOdd, dEven;
while (iter != l.end()) {
if (*iter % 2 == 0)
dEven.insert(dEven.end(), *iter++);
else
dOdd.insert(dOdd.end(), *iter++);
}
for (auto it = dOdd.begin(); it != dOdd.end(); it++)
cout << *it << endl;
}
练习9.21 每次都把vector中的元素依次往后移动
练习9.22 永远不会等于,添加++iter
练习9.23 相等
练习9.25 不删除 返回elem2
练习9.29添加75个默认值, 抛弃第10个后面的值。
练习9.30 有默认构造函数或默认值
练习9.31 迭代器不能+2 加两次
练习9.32 不合法 iter的求值顺序不定
练习9.33 行为未定义
练习9.34 将奇数值复制一次
练习9.35 capacity是不分配内存的最大容量 size是目前元素个数。
练习9.36 不可能
练习9.37 list元素不是相邻的,不需要统一分配内存。 array元素数量固定。
练习9.38 每次两倍。
练习9.39 添加一些空串
练习9.40 512 乘2
练习9.41
int main()
{
vector<char> v = {'1','2','3','4','5'};
string s(v.begin(), v.end());
cout << s <<endl;
return 0;
}
练习9.42 先用vector读取,然后转为string
练习9.43
void change(string& s, string& old, string& news) {
auto sit = s.begin();
auto oit = old.begin();
while(sit != s.end()) {
if (*sit == *oit) {
sit++;
oit++;
}else {
sit++;
oit = old.begin();
}
if (oit == old.end()) {
sit = s.erase(sit-old.size(),sit);
sit = s.insert(sit, news.begin(),news.end());
sit = sit + news.size();
oit = old.begin();
}
}
}
练习9.44
void change(string& s, string& old, string& news) {
auto sit = s.begin();
auto oit = old.begin();
while(sit != s.end()) {
if (*sit == *oit) {
sit++;
oit++;
}else {
sit++;
oit = old.begin();
}
if (oit == old.end()) {
int p = sit - s.begin();
s.replace(p-old.size(), old.size(), news);
sit = s.begin() + p - old.size() + news.size();
}
}
}
练习9.46
string insertAppend(string& s, string& pre, string& suf) {
s.insert(0, pre);
s.insert(s.size(), suf);
return s;
}
练习9.47
void findFirst(string&s, string& num) {
int pos = 0;
while((pos = s.find_first_of(num, pos)) != string::npos) {
cout << "number index: "<< pos << " is "<< s[pos] <<endl;
pos++;
}
pos = 0;
while((pos = s.find_first_not_of(num, pos)) != string::npos) {
cout << "character index: "<< pos << " is "<< s[pos] <<endl;
pos++;
}
}
练习9.48 string::npos
练习9.49
void longest(string& s, string& c) {
int pos = 0;
int left = 0, ll = 0;
int right = 0, rr = 0;
while((pos = s.find_first_of(c,pos)) != string::npos) {
if (pos == rr) {
rr = pos+1;
if (rr - ll > right - left) {
right = rr;
left = ll;
}
}else {
ll = pos;
rr = pos+1;
}
pos++;
}
cout << s.substr(left, right-left);
}
练习9.50
int sumInt(vector<string> v) {
int sum = 0;
for(auto x : v)
sum += stoi(x);
return sum;
}
double sumDouble(vector<string> v) {
double sum = 0;
for(auto x : v)
sum += stod(x);
return sum;
}
练习9.51
class date
{
unsigned year, month, day;
public:
friend void pirntDate(date& d);
date(const string& ss) {
int c = 0;
if (ss.find(",") != string::npos) c = 0;
else if (ss.find("/") != string::npos) c = 1;
else c = 2;
int left=0, right=0;
switch(c) {
case 0:
if (ss.find("Jan") != string::npos) month = 1;
if (ss.find("Feb") != string::npos) month = 2;
if (ss.find("Mar") != string::npos) month = 3;
if (ss.find("Apr") != string::npos) month = 4;
if (ss.find("May") != string::npos) month = 5;
if (ss.find("Jun") != string::npos) month = 6;
if (ss.find("Jul") != string::npos) month = 7;
if (ss.find("Aug") != string::npos) month = 8;
if (ss.find("Sep") != string::npos) month = 9;
if (ss.find("Oct") != string::npos) month = 10;
if (ss.find("Nov") != string::npos) month = 11;
if (ss.find("Dec") != string::npos) month = 12;
left = ss.find(" ");
right = ss.find(",");
day = stoi(ss.substr(left+1,right-left-1));
year = stoi(ss.substr(right+1));
break;
case 1:
left = ss.find_first_of("/",0);
right = ss.find_first_of("/",left+1);
month = stoi(ss.substr(0,left));
day = stoi(ss.substr(left+1, right-left-1));
year = stoi(ss.substr(right+1,4));
break;
case 2:
if (ss.find("Jan") != string::npos) month = 1;
if (ss.find("Feb") != string::npos) month = 2;
if (ss.find("Mar") != string::npos) month = 3;
if (ss.find("Apr") != string::npos) month = 4;
if (ss.find("May") != string::npos) month = 5;
if (ss.find("Jun") != string::npos) month = 6;
if (ss.find("Jul") != string::npos) month = 7;
if (ss.find("Aug") != string::npos) month = 8;
if (ss.find("Sep") != string::npos) month = 9;
if (ss.find("Oct") != string::npos) month = 10;
if (ss.find("Nov") != string::npos) month = 11;
if (ss.find("Dec") != string::npos) month = 12;
left = ss.find_first_of(' ');
right = ss.find_first_of(' ', left+1);
day = stoi(ss.substr(left+1, right-left-1));
year = stoi(ss.substr(right+1));
break;
}
}
};
void pirntDate(date& d){
cout << d.year << "年" << d.month << "月"<< d.day<<"日"<<endl;
}
int main()
{
date d1("January 1, 1900");
pirntDate(d1);
date d2("1/2/1900");
pirntDate(d2);
date d3("Jan 1 1900");
pirntDate(d3);
return 0;
}
练习9.52
思路:中缀表达式的计算。
/*
*说明:中缀表达式求值函数说明
1.扫描表达式
a.如果 token 是 "+","-","*","/"
a1.符号栈为空,token直接入栈
a2.符号栈不空,比较token和栈顶符号的优先级
如果token的优先级高,直接入栈
否则将栈里面的符号出栈,并和数字栈进行计算,设置新的栈顶符号和优先级,一直到优先级低的全部弹出栈,循环停止,新的符号入栈
b.如果 token是 "(",直接入栈
c. 如果token是")"
当stack_opt.top !="(",既没有找到最近的和右括号匹配的左括号
操作符弹出栈,并和操作数计算
最后将"("也弹出去
”)“不进栈,它的作用是为了消除掉最近的左括号) //循环外的pop是将左括号丢弃
d.剩下的情况就都是数字,直接进入操作数栈
*/
int priorityOpt(char opt) {
switch(opt) {
case '(':
return 1;
case '+':
case '-':
return 2;
case '*':
case '/':
return 3;
default:
return 0;
}
}
void compute(stack<int>& val, char opt) {
int right = val.top();
val.pop();
int left = val.top();
val.pop();
int res = 0;
switch(opt) {
case '+':
res = left + right;
break;
case '-':
res = left - right;
break;
case '*':
res = left * right;
break;
case '/':
res = left/right;
break;
}
val.push(res);
}
int getNum(string& s, int& index) {
int left = index;
int right = left+1;
while(right == (s.find_first_of("0123456789",++index)))
right++;
return stoi(s.substr(left,right));
}
int caculator(string& s) {
stack<char> symbol;
stack<int> val;
int res = 0;
int index = 0;
int tmp;
while(index < s.size()) {
if (s[index] == '(')
symbol.push(s[index++]);
else if (s[index] == ')') {
while(symbol.top() != '(') {
compute(val, symbol.top());
symbol.pop();
}
symbol.pop();
index++;
}
else if (s[index] == '+' || s[index] == '-' || s[index]=='*' || s[index]=='/') {
if(symbol.empty())
symbol.push(s[index]);
else if (priorityOpt(s[index]) > priorityOpt(symbol.top())) {
symbol.push(s[index]);
}else {
compute(val, symbol.top());
symbol.pop();
symbol.push(s[index]);
}
index++;
}else {
int num = getNum(s,index);
val.push(num);
}
}
while(!symbol.empty()){
compute(val, symbol.top());
symbol.pop();
}
return val.top();
}
int main()
{
string s = "((1+2)*4+3/2-5)+3";
cout<<caculator(s)<<endl;
return 0;
}