第十六章:string类和标准模板库
一、复习题
1. RQ1(const char * s),RQ1(),~RQ1(){}
2. 第一、string类可以自动调整大小以匹配字符串;第二、string对象重载了运算符,其使用比C-风格字符串更方便。
3.
const String & toUpperCase(string & str)
{
for(int i = 0; i < str.size(); ++i)
{
str[i] = toupper(str[i]);
}
return str;
}
4. 第一(不能使用new []),第二,第四(必须要和new运算符搭配)和第五个
5. 因为高尔夫球棍的袋子并不符合栈“先进后出”的设计理念。
6. 集合将只存储每个值的一个拷贝,5个5分会变成一个5分
7. 因为需要用迭代器这个概念与所有的容器匹配,从而避免重复编写许多段高度相似的代码。
8. 避免编写重复的代码,提高代码的复用性。
9. 第一、大小可自动调整;第二、vector可以使用stl中的许多算法;第三、可以将一个vector赋值给另一个vector。
10.这两个vector 函数和 random shuffle()函数要求随机访问迭代器,而list 对象只有双向迭代器。可以使用 list 模板类的 sort()成员函数,而不是通用两数来排序,但没有random_shuffe()等效的成员两数。然而,可以将链表复制到矢量中,然后打乱矢量,并将结果重新复制到链表中。
11.创建了一个成员变量值为10的TooBig对象,调用了其opreator()函数,传递参数15进入函数,返回结果10 < 15,故bo是true。
二、编程练习
1.
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
bool isPalindrome(const string& src);
int main()
{
cout << isPalindrome("aaabbaaa") << '\n';
cout << isPalindrome("aaabcaa");
return 0;
}
bool isPalindrome(const string& src)
{
string newStr = src.substr(src.size()/2);
reverse(newStr.begin(),newStr.end());
return src.substr(0,src.size()/2) == newStr;
}
2.
#include <iostream>
#include <string>
#include <cctype>
#include <algorithm>
using namespace std;
bool isPalindrome(string& src);
int main()
{
string str = "Madam, I'm Adam";
cout << isPalindrome(str);
return 0;
}
bool isPalindrome(string& src)
{
src.erase(remove_if(src.begin(), src.end(),static_cast<int(*)(int)>(&ispunct)),src.end());
src.erase(remove_if(src.begin(), src.end(),static_cast<int(*)(int)>(&isspace)),src.end());
for(int i = 0; i < src.size(); ++i)
src[i] = tolower(src[i]);
string newStr = src.substr(src.size()/2+1);
reverse(newStr.begin(),newStr.end());
return src.substr(0,src.size()/2) == newStr;
}
3.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <cctype>
using namespace std;
vector<string> wordlist;
int main()
{
ifstream ifs;
ifs.open("wordlist");
if(!ifs.is_open())
{
return 0;
}
while(!ifs.eof())
{
string str;
ifs >> str;
wordlist.push_back(str);
}
srand(time(0));
char play;
cout << "Will you play a word game? <y/n> : ";
cin >> play;
play = tolower(play);
while(play == 'y')
{
string target = wordlist[rand()%wordlist.size()];
int length = target.size();
string attempt(length,'-');
string badChars;
int guesses = 6;
cout << "Guess my secret word. It has " << length
<< " letters, and you guess\n"
<< "one letter at a time. You get " << guesses
<< " wrong guesses.\n";
cout << "Your word: " << attempt << endl;
while(guesses > 0 && attempt != target)
{
char letter;
cout << "Guess a letter: ";
cin >> letter;
if(badChars.find(letter) != string::npos ||
attempt.find(letter) != string::npos)
{
cout << "You already guessed that. Try again.\n";
continue;
}
int loc = target.find(letter);
if(loc == string::npos)
{
cout << "Bad guess!\n";
--guesses;
badChars += letter;
}
else
{
cout << "Good guess!\n";
attempt[loc] = letter;
loc = target.find(letter,loc+1);
while(loc != string::npos)
{
attempt[loc] = letter;
loc = target.find(letter,loc+1);
}
}
cout << "Your word: " << attempt << endl;
if(attempt != target)
{
if(badChars.size() > 0)
{
cout << "Bad choices: " << badChars << endl;
}
cout << guesses << " bad guesses left.\n";
}
}
if(guesses > 0)
{
cout << "That's right!\n";
}
else
{
cout << "Sorry, the word is " << target << "\n";
cout << "Will you play another? <y/n> : ";
cin >> play;
play = tolower(play);
}
cout << "Bye!\n";
}
return 0;
}
4.
#include <iostream>
#include <algorithm>
using namespace std;
int reduce(long ar[], int n);
int main()
{
long ar[8] = {1,2,4,4,4,5,5,7};
cout << reduce(ar,8);
return 0;
}
int reduce(long ar[], int n)
{
long* pr = unique(ar,ar+n);
return static_cast<int>(ar+n-pr);
}
5.
#include <iostream>
#include <algorithm>
using namespace std;
template<class T>
int reduce(T ar[], int n);
int main()
{
long ar[8] = {1,2,4,4,4,5,5,7};
cout << reduce(ar,8) << endl;
string arStr[8] = {"a","b","c","c","c","d","d","d"};
cout << reduce(arStr,8) << endl;
return 0;
}
template<class T>
int reduce(T ar[], int n)
{
T* pr = unique(ar,ar+n);
return static_cast<int>(ar+n-pr);
}
6.
#include <iostream>
#include <queue>
#include <cstdlib>
#include <ctime>
using namespace std;
class Customer
{
long arrive;
int processtime;
public:
Customer() {arrive = processtime = 0;}
void set(long when) {processtime = rand()%3 + 1; arrive = when;}
long when() const { return arrive;}
int ptime() const { return processtime;}
};
const int MIN_PER_HR = 60;
bool newcustomer(double x);
int main()
{
srand(time(0));
cout << "Case Study: Bank of Heather Automatic Teller\n";
cout << "Enter maximum size of queue: ";
int qs;
cin >> qs;
queue<Customer> line;
cout << "Enter the number of simulation hours: ";
int hours;
cin >> hours;
long cyclelimit = MIN_PER_HR * hours;
cout << "Enter the average number of customers per hour: ";
double perhour;
cin >> perhour;
double min_per_cust;
min_per_cust = MIN_PER_HR / perhour;
Customer temp;
long turnaways = 0;
long customers = 0;
long served = 0;
long sum_line = 0;
int wait_time = 0;
long line_wait = 0;
for(int cycle = 0; cycle < cyclelimit; cycle++)
{
if(newcustomer(min_per_cust))
{
if(qs == line.size())
turnaways++;
else
{
customers++;
temp.set(cycle);
line.push(temp);
}
}
if(wait_time <= 0 && !line.empty())
{
temp = line.front();
wait_time = temp.ptime();
line_wait += cycle - temp.when();
served++;
line.pop();
}
if(wait_time > 0)
wait_time--;
sum_line += line.size();
}
if(customers > 0)
{
cout << "customers accepted: " << customers << endl;
cout << " customers served: " << served << endl;
cout << " turnaways: " << turnaways << endl;
cout << "average queue size: " ;
cout.precision(2);
cout.setf(ios_base::fixed, ios_base::floatfield);
cout << (double)sum_line / cyclelimit << endl;
cout << " average wait time: "
<< (double)line_wait / served << " minutes\n";
}
else
cout << "No customers!\n";
cout << "Done!\n";
return 0;
}
bool newcustomer(double x)
{
return (rand() * x / RAND_MAX < 1);
}
7.
#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
using namespace std;
vector<int> Lotto(int t, int n);
int main()
{
vector<int> winner = Lotto(51,6);
for_each(winner.begin(),winner.end(),[](int x){
cout << x << " ";
});
return 0;
}
vector<int> Lotto(int t, int n)
{
vector<int> ans;
vector<int> temp;
for(int i = 0; i < t; ++i)
temp.push_back(i+1);
unsigned seed = chrono::system_clock::now().time_since_epoch().count();
for(int i = 0; i < n ; ++i)
{
shuffle(temp.begin(), temp.end(), default_random_engine(seed));
ans.push_back(temp.front());
}
return ans;
}
8.
#include <iostream>
#include <set>
using namespace std;
void showName(const string& name);
int main()
{
set<string> mat;
set<string> pad;
string name;
cout << "Mat's friend: (q to quit)";
while(cin >> name)
{
if(name == "q")
break;
mat.insert(name);
cout << "Next: ";
}
cout << "Pad's friend: (q to quit)";
while(cin >> name)
{
if(name == "q")
break;
pad.insert(name);
cout << "Next: ";
}
for_each(mat.begin(),mat.end(), showName);
cout << endl;
for_each(pad.begin(),pad.end(), showName);
cout << endl;
set<string> ans;
set_union(mat.begin(),mat.end(),pad.begin(),pad.end(), inserter(ans,ans.begin()));
for_each(ans.begin(),ans.end(), showName);
return 0;
}
void showName(const string& name)
{
cout << name << " ";
}
9.
#include <iostream>
#include <vector>
#include <list>
#include <ctime>
using namespace std;
int main()
{
srand(time(0));
vector<int> vi0;
for(int i = 0; i < 10000000; i++)
vi0.push_back(rand());
list<int> li;
vector<int> vi;
for(int x : vi0)
{
li.push_back(x);
vi.push_back(x);
}
cout << "Vector sort: " << endl;
clock_t start = clock();
sort(vi.begin(),vi.end());
cout << (double)(clock() - start)/CLOCKS_PER_SEC << endl;
cout << "List sort: " << endl;
start = clock();
li.sort();
cout << (double)(clock() - start)/CLOCKS_PER_SEC << endl;
cout << "List copy and sort: " << endl;
start = clock();
copy(vi0.begin(),vi0.end(),vi.begin());
sort(vi.begin(),vi.end());
copy(vi.begin(),vi.end(),li.begin());
cout << (double)(clock() - start)/CLOCKS_PER_SEC << endl;
return 0;
}
10.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <memory>
using namespace std;
struct Review
{
string title;
int rating;
int price;
};
bool FillReview(shared_ptr<Review>& p);
void ShowReview(shared_ptr<Review>& p);
bool worsethan(shared_ptr<Review>& pa,shared_ptr<Review>& pb);
bool betterthan(shared_ptr<Review>& pa,shared_ptr<Review>& pb);
bool cheapthan(shared_ptr<Review>& pa,shared_ptr<Review>& pb);
bool expensivethan(shared_ptr<Review>& pa,shared_ptr<Review>& pb);
bool operator<(shared_ptr<Review>& pa,shared_ptr<Review>& pb);
int main()
{
vector<shared_ptr<Review>> books;
while(true)
{
shared_ptr<Review> pBook(new Review);
if(!FillReview(pBook))
break;
books.push_back(pBook);
}
if(books.size() > 0){
cout << "Thank you. You entered the following "
<< books.size() << " ratings:\n"
<< "Rating\tBook\t" << "Prices\n";
for_each(books.begin(), books.end(), ShowReview);
cout << "Please choose a type to show(0 for original order, 1 for alphabet order, 2 for rating ascend order, \n3 for rating discend order, 4 for price ascend order, 5 for price discend order, q for quit): ";
int input;
while (cin >> input)
{
switch (input)
{
case 0:
break;
case 1:
sort(books.begin(), books.end());
break;
case 2:
sort(books.begin(), books.end(), worsethan);
break;
case 3:
sort(books.begin(), books.end(), betterthan);
break;
case 4:
sort(books.begin(), books.end(), cheapthan);
break;
case 5:
sort(books.begin(), books.end(), expensivethan);
break;
default:
break;
}
for_each(books.begin(), books.end(), ShowReview);
cout << "Please choose a type to show(0 for original order, 1 for alphabet order, 2 for rating ascend order, \n3 for rating discend order, 4 for price ascend order, 5 for price discend order, q for quit): ";
}
}
else
cout << "No entries. ";
cout << "Bye.\n";
return 0;
}
bool FillReview(shared_ptr<Review>& p)
{
cout << "Enter the book title: (quit to quit): ";
getline(cin,p->title);
if(p->title == "quit")
return false;
cout << "Enter book rating: ";
cin >> p->rating;
if(!cin)
return false;
cout << "Enter book price: ";
cin >> p->price;
if(!cin)
return false;
while(cin.get() != '\n');
return true;
}
void ShowReview(shared_ptr<Review>& p)
{
cout << p->rating << "\t" << p->title << "\t" << p->price << endl;
}
bool worsethan(shared_ptr<Review>& pa,shared_ptr<Review>& pb)
{
return pa->rating < pb->rating;
}
bool betterthan(shared_ptr<Review>& pa,shared_ptr<Review>& pb)
{
return pa->rating > pb->rating;
}
bool cheapthan(shared_ptr<Review>& pa,shared_ptr<Review>& pb)
{
return pa->price < pb->price;
}
bool expensivethan(shared_ptr<Review>& pa,shared_ptr<Review>& pb)
{
return pa->price > pb->price;
}
bool operator<(shared_ptr<Review>& r1,shared_ptr<Review>& r2)
{
if (r1->title < r2->title)
return true;
else if (r1->title == r2->title && r1->rating < r2->rating)
return true;
else return false;
}