c++ primer 第九章习题

练习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;
}

猜你喜欢

转载自blog.csdn.net/qq_25037903/article/details/81777933