练习9.1
答:a选list,因为需要从容器的中间位置插入元素;b选vector,因为只需要在尾部插入元素;c没有最优,选择vector
练习9.2
list<deque<int>> l;
练习9.3
答:指向同一个容器的元素,并且end不在begin前
练习9.4
bool isExit(vector<int> v, int a)
{
for (auto i = v.begin();i!=v.end();++i)
if (*i == a)
return true;
return false;
}
练习9.5
vector<int>::iterator isExit(vector<int> &v, int a)
{
for (auto it = v.begin(); it != v.end(); ++it)
if (*it == a)
return it;
return v.end();
}
练习9.6
答:小于号错误,应该使用等于号
练习9.7
答:const_iterator
练习9.8
答:const_iterator, iterator
练习9.9
答:begin返回的是iterator,cbegin返回的是const_iterator
练习9.10
答:reference;const_reference;iterator;const_iterator
练习9.11
vector<int> a1;//创建一个空容器
vector<int> a2(10);//创建一个空容器,大小为10个元素
vector<int> a3(10, 1);//创建一个大小为10个元素的容器,其中每个值都为1
vector<int> a4(a2);//用a2的值初始化
vector<int> a5{ 1,2,3,4,5,6 };//大小为六,值为1,2,3,4,5,6
vector<int> a6(a3.begin(), a3.end());//用a3的值初始化
练习9.12
答:接受一个容器的,两容器类型必须相同;接受迭代器的可以不同
练习9.13
list<int> l = {1,2,3,4,5};
vector<int> v1 = {1,2,3,4,5};
vector<double> v2(l.begin(),l.end());
vector<double> v3(v1.begin(),v1.end());
练习9.14
list<char *> l = {'1','2','3'};
vector<string> s(l);
练习9.15
bool isEqual(vector<int> v1,vector<int> v2)
{
if(v1==v2)
return true;
return false;
}
练习9.16
bool isEqual(vector<int> v1, list<int> l1)
{
int i = 0;
for (auto const& a : l1)
{
*v1.begin()++ != a;
return false;
}
return true;
}
练习9.17
答:容器类型和元素类型必须相同
练习9.18
int main()
{
string s;
deque<string> d;
while (cin >> s)
d.push_back(s);
for (auto i = d.begin(); i != d.end(); ++i)
cout << *i << " ";
return 0;
}
练习9.19
int main()
{
string s;
list<string> d;
while (cin >> s)
d.push_back(s);
for (auto i = d.begin(); i != d.end(); ++i)
cout << *i << " ";
return 0;
}
练习9.20
int main()
{
list<int> l = { 1,2,3,4,5,6 };
vector<int> v1;
vector<int> v2;
for (auto const& a : l)
{
if (a % 2 == 0)
v2.push_back(a);
else
v1.push_back(a);
}
return 0;
}
练习9.21
vector<string> v1;
string word;
auto iter = v1.begin();
while (cin >> word)
iter = v1.insert(iter, word);
练习9.22
答:循环不会终止
while (iter != mid) {
if (*iter == some_val) {
iter = iv.insert(iter, 2 * some_val);
++iter; // 插入后移动迭代器到下一个位置
mid = iv.begin() + iv.size() / 2; // 重新计算 mid
}
++iter;
}
练习9.23
答:值都相同
练习9.24
int main()
{
vector<int> v1 = { 1,2,3,4,5,6 };
vector<int> v2 = { v1[0],v1.at(0),v1.front(),*v1.begin() };
for (auto const& a : v2)
cout << a << " ";
return 0;
}
练习9.25
答:若elem1与elem2相等,则删除的范围为空;若elem1与elem2皆为尾后迭代器,则不会删除元素
练习9.26
int main()
{
int ia[] = { 0,1,1,2,3,5,8,13,21,55,89 };
vector<int> v1;
list<int> l1;
for (int i = 0; i <11; ++i)
{
v1.push_back(ia[i]);
l1.push_back(ia[i]);
}
for (auto i = v1.begin(); i != v1.end(); ++i)
{
if (*i % 2 == 0)
i = v1.erase(i);
}
for (auto i = l1.begin(); i != l1.end(); ++i)
{
if (*i % 2 != 0)
i = l1.erase(i);
}
return 0;
}
练习9.27
forward_list<int> v1;
auto pre = v1.before_begin();
auto i = v1.begin();
for (; i != v1.end(); ++i)
{
if (*i % 2 != 0)
i = v1.erase_after(pre);
else
{
pre = i;
++i;
}
}
练习9.28
void myInsert(forward_list<string> s1,string s2, string s3)
{
auto i = s1.begin();
for (; i != s1.end(); ++i)
{
if (*i == s2)
{
s1.insert_after(i, s3);
return;
}
}
s1.insert_after(i,s3);
}
练习9.29
答:将容器大小扩展为100;将容器大小减小为10
练习9.30
答:如果是类类型元素,则该类必须有默认构造函数。
练习9.31
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); // 复制当前元素
advance(iter, 2); // 向前移动迭代器,跳过当前元素以及插入到它之前的元素
} else {
iter = vi.erase(iter); // 删除偶数元素,erase 返回下一个有效迭代器
}
}
练习9.32
答:不合法,因为函数可能先计算iter或先计算*iter++,所以不合法
练习9.33
答:每次修改的值都会是新插入的值
练习9.34
答:将偶数值元素复制
练习9.35
答:capacity是查询能容纳的元素个数,size是当前容器拥有的元素个数
练习9.36
答:不可能
练习9.37
答:list不是预分配一块连续的内存,其内存需求是动态变化的,不存在容量限制;array的大小是在创建时就确定的
练习9.38
vector<int> v1;
v1.reserve(50);
while (v1.size() != v1.capacity())
v1.push_back(0);
cout << "size:" << v1.size() << endl;
cout << "capacity:" << v1.capacity() << endl;
v1.push_back(0);
cout << "size:" << v1.size() << endl;
cout << "capacity:" << v1.capacity() << endl;
运行结果如下:
练习9.39
答:向容器中添加元素,每次读取结束,将容器大小扩大二分之一
练习9.40
答:1536,1536,1536,2304
练习9.41
vector<char> v1 = { 'a' };
string s1(v1.begin(),v1.end());
练习9.42
string str;
str.reserve(100); // 预分配至少 100 个字符的空间
char ch;
int count = 0;
while (std::cin.get(ch)) { // 从标准输入读取字符,假设每次读取一个字符
str.push_back(ch);
count++;
if (count >= 100) break; // 假设我们只读取 100 个字符
}
练习9.43
void replaceString(string &s, const string &oldVal, const string &newVal) {
auto it = s.begin();
while (it != s.end()) {
// 检查当前迭代器位置后的子串是否等于 oldVal
if (std::string(it, it + oldVal.size()) == oldVal) {
// 使用 erase 和 insert 替换子串
it = s.erase(it, it + oldVal.size());
it = s.insert(it, newVal.begin(), newVal.end());
// 移动迭代器到新插入部分的末尾
it += newVal.size();
} else {
++it;
}
}
}
练习9.44
void replaceString(string &s, const string &oldVal, const string &newVal) {
size_t pos = 0;
while ((pos = s.find(oldVal, pos)) != string::npos) {
s.replace(pos, oldVal.size(), newVal);
pos += newVal.size(); // 移动位置以避免重复替换
}
}
练习9.45
std::string addPrefixSuffix(const string &name, const string &prefix, const string &suffix) {
string result = name;
result.insert(result.begin(), prefix.begin(), prefix.end());
result.append(suffix);
return result;
}
练习9.46
string addPrefixSuffix(const string &name, const string &prefix, const string &suffix) {
string result = name;
result.insert(0, prefix); // 插入前缀
result.insert(result.size(), suffix); // 插入后缀
return result;
}
练习9.47
void findDigitsAndLettersUsingFindFirstOf(const string &str) {
string numbers = "0123456789";
string letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
string::size_type pos = 0;
// 查找数字字符
cout << "Digits: ";
while ((pos = str.find_first_of(numbers, pos)) != string::npos) {
cout << str[pos] << ' ';
++pos;
}
cout << endl;
pos = 0;
// 查找字母字符
cout << "Letters: ";
while ((pos = str.find_first_of(letters, pos)) != std::string::npos) {
std::cout << str[pos] << ' ';
++pos;
}
cout << std::endl;
}
练习9.49
ifstream file("words.txt");
if (!file) {
cerr << "Cannot open file." << endl;
return 1;
}
set<char> ascenders = {'b', 'd', 'f', 'h', 'k', 'l', 't'};
set<char> descenders = {'g', 'j', 'p', 'q', 'y'};
string longestWord;
string word;
while (file >> word) {
bool hasAscenderOrDescender = false;
for (char c : word) {
if (ascenders.count(c) || descenders.count(c)) {
hasAscenderOrDescender = true;
break;
}
}
if (!hasAscenderOrDescender && word.length() > longestWord.length()) {
longestWord = word;
}
}
cout << "The longest word without ascenders or descenders is: " << longestWord << std::endl;
练习9.50
// 计算整型值的和
int sumOfIntegers(const vector<string>& vec) {
int sum = 0;
for (const auto& str : vec) {
sum += stoi(str);
}
return sum;
}
// 计算浮点值的和
double sumOfDoubles(const vector<string>& vec) {
double sum = 0.0;
for (const auto& str : vec) {
sum += stod(str);
}
return sum;
}
练习9.51
class Date {
public:
Date(const string& dateStr) {
parseDate(dateStr);
}
void printDate() const {
cout << year << "-" << month << "-" << day << endl;
}
private:
unsigned year = 0, month = 0, day = 0;
const map<string, unsigned> monthMap = {
{"January", 1}, {"February", 2}, {"March", 3}, {"April", 4},
{"May", 5}, {"June", 6}, {"July", 7}, {"August", 8},
{"September", 9}, {"October", 10}, {"November", 11}, {"December", 12},
{"Jan", 1}, {"Feb", 2}, {"Mar", 3}, {"Apr", 4},
{"May", 5}, {"Jun", 6}, {"Jul", 7}, {"Aug", 8},
{"Sep", 9}, {"Oct", 10}, {"Nov", 11}, {"Dec", 12}
};
void parseDate(const std::string& dateStr) {
istringstream iss(dateStr);
string monthStr, dayStr, yearStr;
if (isalpha(dateStr[0])) {
// Case: "January 1, 1900" or "Jan 1 1900"
iss >> monthStr >> dayStr >> yearStr;
dayStr.pop_back(); // Remove comma if present
} else if (isdigit(dateStr[0])) {
// Case: "1/1/1990"
getline(iss, monthStr, '/');
getline(iss, dayStr, '/');
getline(iss, yearStr);
}
if (isdigit(monthStr[0])) {
month = stoul(monthStr);
} else {
month = monthMap.at(monthStr);
}
day = stoul(dayStr);
year = stoul(yearStr);
}
};