一、9.2.1 迭代器
节练习 9.4
// chapter9_2.cpp
#include <iostream>
#include <vector>
using namespace std;
using std::vector;
vector<int> v = {2,4,63,75,34,57,234,543,678,975,4322};
bool find(vector<int>::iterator it1, vector<int>::iterator it2, int data) {
while (it1 != it2)
{
if (*it1 == data) {
cout << "find the data " << data << endl;
return true;
}
it1 ++;
}
cout << "not find the data " << data << endl;
return false;
}
int main(){
find(v.begin(), v.end(), 23);
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_2 chapter9_2.cpp
节练习 9.5
// chapter9_2.cpp
#include <iostream>
#include <vector>
using namespace std;
using std::vector;
vector<int> v = {2,4,63,75,34,57,234,543,678,975,4322};
vector<int>::iterator find(vector<int>::iterator it1, vector<int>::iterator it2, int data) {
while (it1 != it2)
{
if (*it1 == data) {
cout << "find the data " << data << endl;
return it1;
}
it1 ++;
}
cout << "not find the data " << data << endl;
return it1;
}
int main(){
vector<int>::iterator it = find(v.begin(), v.end(), 4322);
if (it == v.end()) {
cout << "not find the data "<< endl;
} else {
cout << "find the data " << endl;
}
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_2 chapter9_2.cpp
// 节练习 9.14
// chapter9_2.cpp
#include <iostream>
#include <vector>
#include <list>
using namespace std;
using std::vector;
using std::list;
int main(){
list<char*> l = {"nihao", "hello word", "output"};
vector<string> v;
v.assign(l.begin(),l.end());
cout << "ventor data is ";
vector<string>::iterator it = v.begin();
while(it != v.end()) {
cout << *it << ",";
it ++;
}
// for (int i = 0; i < v.size(); i ++) {
// cout << v.at(i) << ",";
// }
cout << endl;
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_2 chapter9_2.cpp
// 节练习 9.15
// chapter9_2.cpp
#include <iostream>
#include <vector>
using namespace std;
using std::vector;
int main()
{
vector<int> v1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
vector<int> v2 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
// vector<int> v2 = {11, 21, 31, 41, 51, 61, 71, 81, 91, 10};
if (v1 == v2)
{
cout << "vector v1 == v1" << endl;
}
else
{
cout << "vector v1 != v1" << endl;
}
return 0;
}
// 编译 : g++ -std=c++11 -o chapter9_2 chapter9_2.cpp
// 节练习 9.16
// chapter9_2.cpp
#include <iostream>
#include <vector>
#include <list>
using namespace std;
using std::vector;
using std::list;
int main()
{
list<int> l = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
vector<int> v = {1, 2, 3, 4, 5, 16, 7, 8, 9};
// vector<int> v2 = {11, 21, 31, 41, 51, 61, 71, 81, 91, 10};
list<int>::iterator it1 = l.begin();
vector<int>::iterator it2 = v.begin();
while (it1 != l.end() && it2 != v.end())
{
if (*it1 == *it2) {
cout << "the data is same " << *it1 << endl;
} else {
cout << "the data is not same " << *it1 << "," << *it2<< endl;
}
it1 ++;
it2 ++;
}
return 0;
}
// 编译 : g++ -std=c++11 -o chapter9_2 chapter9_2.cpp
// 节练习 9.18
// chapter9_3.cpp
#include <iostream>
#include <deque>
using namespace std;
using std::deque;
int main() {
cout << "please input some data :" ;
string s;
deque<string> d;
while (cin >> s && s != "q") {
d.push_back(s);
}
deque<string>::iterator it = d.begin();
while (it != d.end())
{
cout << "data is : " << *it << endl;
it ++ ;
}
return 0;
}
编译: g++ -std=c++11 -o chapter9_3 chapter9_3.cpp
// 节练习 9.19
// chapter9_3.cpp
#include <iostream>
#include <list>
using namespace std;
using std::list;
int main() {
cout << "please input some data :" ;
string s;
list<string> d;
while (cin >> s && s != "q") {
d.push_back(s);
}
list<string>::iterator it = d.begin();
while (it != d.end())
{
cout << "list data is : " << *it << endl;
it ++ ;
}
return 0;
}
编译: g++ -std=c++11 -o chapter9_3 chapter9_3.cpp
// 节练习 9.20
// chapter9_3.cpp
#include <iostream>
#include <list>
#include <deque>
using namespace std;
using std::list;
using std::deque;
int main()
{
list<int> l = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
deque<int> d1;
deque<int> d2;
if (l.size() == 0)
{
cout << "the list is null" << endl;
return 1;
}
list<int>::iterator it_l = l.begin();
while (it_l != l.end())
{
if (*it_l % 2 == 0) {
d1.push_back(*it_l);
} else {
d2.push_back(*it_l);
}
it_l ++;
}
deque<int>::iterator it_d1 = d1.begin();
cout << "deque 1 data is " ;
while (it_d1 != d1.end())
{
cout << *it_d1 << " ";
it_d1 ++;
}
cout << endl;
deque<int>::iterator it_d2 = d2.begin();
cout << "deque 2 data is " ;
while (it_d2 != d2.end())
{
cout << *it_d2 << " ";
it_d2 ++;
}
cout << endl;
return 0;
}
编译: g++ -std=c++11 -o chapter9_3 chapter9_3.cpp
// 节练习 9.24
// chapter9_3.cpp
#include <iostream>
#include <vector>
using namespace std;
using std::vector;
int main()
{
vector<int> v;
// vector<int> v = {9, 2, 3, 4, 56, 7, 8, 9, 0};
if (v.size() == 0)
{
cout << "the vector is null" << endl;
return 1;
}
cout << "at the first data is " << v.at(0) << endl;
cout << " the first data is " << v[0] << endl;
cout << " front the first data is " << v.front() << endl;
cout << " begin the first data is " << *(v.begin()) << endl;
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_3 chapter9_3.cpp
// 节练习 9.26
// chapter9_3.cpp
#include <iostream>
#include <list>
#include <vector>
using namespace std;
using std::list;
using std::vector;
int main()
{
int ia[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
// copy
vector<int> v(begin(ia),end(ia));
list<int> l(begin(ia),end(ia));
if (v.size() == 0)
{
cout << "the vector is null" << endl;
return 1;
}
if (l.size() == 0)
{
cout << "the list is null" << endl;
return 1;
}
// erase
list<int>::iterator it_l = l.begin();
while (it_l != l.end())
{
if (*it_l % 2 == 1) {
it_l = l.erase(it_l);
} else {
it_l ++;
}
}
vector<int>::iterator it_v = v.begin();
while (it_v != v.end())
{
if (*it_v % 2 == 0) {
it_v = v.erase(it_v);
} else {
it_v ++;
}
}
// print
it_l= l.begin();
cout << "list data is " ;
while (it_l != l.end())
{
cout << *it_l << " ";
it_l ++;
}
cout << endl;
it_v= v.begin();
cout << "vector data is " ;
while (it_v != v.end())
{
cout << *it_v << " ";
it_v ++;
}
cout << endl;
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_3 chapter9_3.cpp
// 节练习 9.27
// chapter9_3.cpp
#include <iostream>
#include <forward_list>
using namespace std;
// using std::forward_list;
int main()
{
forward_list<int> l = {0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
if (l.empty())
{
cout << "the list is null" << endl;
return 1;
}
// erase
forward_list<int>::iterator pre = l.before_begin();
forward_list<int>::iterator current = l.begin();
while (current != l.end())
{
if (*current % 2 == 1) {
current = l.erase_after(pre);
} else {
pre = current;
current ++;
}
}
// print
current= l.begin();
cout << "list data is " ;
while (current != l.end())
{
cout << *current << " ";
current ++;
}
cout << endl;
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_3 chapter9_3.cpp
// 节练习 9.28
// chapter9_3.cpp
#include <iostream>
#include <forward_list>
using namespace std;
// using std::forward_list;
int find_and_add_data(forward_list<string>l, string s1, string s2) {
forward_list<string>::iterator current = l.begin();
bool isFind = false;
// 查找并插入字符串
while (current != l.end())
{
if (*current == s1) {
isFind = true;
current = l.insert_after(current,s2);
} else {
current ++;
}
}
// 未查找到指定字符串,则在最后添加
if (!isFind) {
current = l.begin();
forward_list<string>::iterator pre = l.before_begin();
while(current != l.end()) {
current ++;
pre ++;
}
l.insert_after(pre,s2);
}
// 打印
current = l.begin();
cout << "list data is " ;
while (current != l.end())
{
cout << *current << " ";
current ++;
}
cout << endl;
return 0;
}
int main()
{
forward_list<string> l1 = {"0", "1", "1", "2", "3", "5", "8", "13", "21", "55", "89" };
find_and_add_data(l1,"1","66");
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_3 chapter9_3.cpp
// 节练习 9.31 (forward_list)
// chapter9_3.cpp
#include <iostream>
#include <forward_list>
using namespace std;
// using std::forward_list;
int erase_and_add_data(forward_list<int>l) {
cout << "erase_and_add_data..." <<endl;
forward_list<int>::iterator pre = l.before_begin();
forward_list<int>::iterator current = l.begin();
// 查找并插入字符串
while (current != l.end())
{
if (*current % 2 == 0) { // 偶数
current = l.erase_after(pre); // 迭代器返回一个指向呗删元素之后元素的迭代器
} else { // 奇数
current = l.insert_after(current,*current); // 迭代器返回一个指向最后一个插入元素的迭代器
pre = current;
current ++;
}
}
// 打印
current = l.begin();
cout << "list data is " ;
while (current != l.end())
{
cout << *current << " ";
current ++;
}
cout << endl;
return 0;
}
int main()
{
forward_list<int> l1 = {5, 1, 1, 2, 3, 4, 8, 12, 21, 55, 89 };
erase_and_add_data(l1);
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_3 chapter9_3.cpp
// 节练习 9.31 (list)
// chapter9_3.cpp
#include <iostream>
#include <list>
using namespace std;
// using std::forward_list;
int erase_and_add_data(list<int>l) {
cout << "erase_and_add_data..." <<endl;
list<int>::iterator current = l.begin();
// 查找并插入字符串
while (current != l.end())
{
if (*current % 2 == 0) { // 偶数
current = l.erase(current); // 迭代器返回一个指向呗删元素之后元素的迭代器
} else { // 奇数
current = l.insert(current,*current); // 迭代器返回一个指向最后一个插入元素的迭代器
cout << "data is " << *current << endl;
current = next(current ,2);
}
}
// 打印
current = l.begin();
cout << "list data is " ;
while (current != l.end())
{
cout << *current << " ";
current ++;
}
cout << endl;
return 0;
}
int main()
{
list<int> l1 = {5, 1, 1, 2, 3, 4, 8, 12, 21, 55, 89 };
/* list 容器next方法:current = l1.begin()对应的迭代器所指的元素是5。
next(current, 16)返回迭代器所指元素是3;
next(current, 10)返回迭代器所指元素是89,与l1.end()不相等;
next(current, 10)返回迭代器所指元素是11(是容器列表中元素个数),与l1.end()相等。
其他容器的next用法还没研究,也就是说使用next方法时,要计算迭代器的步移要小于容器当前迭代器到尾迭代器的距离。
list<int>::iterator current = l1.begin();
current = next(current , 11);
if (current == l1.end()) {
cout << "=======" << *current << endl;
}else {
cout << "=======!!!!!!!!!!!!!!" << *current << endl;
}
*/
erase_and_add_data(l1);
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_3 chapter9_3.cpp
节练习 9.37: 为什么list或array没有capacity成员函数。
deepseek 回答:
1.链表是动态分配的:每个元素单独分配内存(节点包含数据和前后指针)
2.不需要预分配内存:每次插入只需为新节点分配内存,无需为后续元素预留空间
3.内存不连续:不需要像 vector 那样维护连续的存储空间
4.每次插入都是 O(1):不需要重新分配内存和移动现有元素
// 节练习 9.41(来自deepseek)
// chapter9_4.cpp
#include <iostream>
#include <vector>
#include <string>
#include <algorithm> // 用于std::copy
// 方法1:使用迭代器构造函数(最安全、最推荐)
std::string vectorToString1(const std::vector<char>& vec) {
return std::string(vec.begin(), vec.end());
}
// 方法2:使用data()和size()(C++11,高效)
std::string vectorToString2(const std::vector<char>& vec) {
if (vec.empty()) {
return "";
}
return std::string(vec.data(), vec.size());
}
// 方法3:使用指针(兼容旧代码)
std::string vectorToString3(const std::vector<char>& vec) {
if (vec.empty()) {
return "";
}
return std::string(&vec[0], vec.size());
}
// 方法4:使用std::accumulate(函数式风格)
#include <numeric>
std::string vectorToString4(const std::vector<char>& vec) {
return std::accumulate(vec.begin(), vec.end(), std::string());
}
// 方法5:手动构建(教育目的)
std::string vectorToString5(const std::vector<char>& vec) {
std::string result;
result.reserve(vec.size()); // 预分配内存提高效率
for (char c : vec) {
result += c;
}
return result;
}
// 测试函数
void testAllMethods() {
std::vector<char> vec = {'H', 'e', 'l', 'l', 'o', ' ', 'C', '+', '+'};
std::vector<char> empty_vec;
std::vector<char> null_terminated = {'T', 'e', 's', 't', '\0', 'i', 'g', 'n', 'o', 'r', 'e'};
std::cout << "=== 测试正常vector ===" << std::endl;
std::cout << "方法1: \"" << vectorToString1(vec) << "\"" << std::endl;
std::cout << "方法2: \"" << vectorToString2(vec) << "\"" << std::endl;
std::cout << "方法3: \"" << vectorToString3(vec) << "\"" << std::endl;
std::cout << "方法4: \"" << vectorToString4(vec) << "\"" << std::endl;
std::cout << "方法5: \"" << vectorToString5(vec) << "\"" << std::endl;
std::cout << "\n=== 测试空vector ===" << std::endl;
std::cout << "方法1: \"" << vectorToString1(empty_vec) << "\"" << std::endl;
std::cout << "方法2: \"" << vectorToString2(empty_vec) << "\"" << std::endl;
std::cout << "方法3: \"" << vectorToString3(empty_vec) << "\"" << std::endl;
std::cout << "\n=== 测试包含null字符的vector ===" << std::endl;
std::cout << "注意:如果vector中包含'\\0',构造string时可能会截断" << std::endl;
std::string str(null_terminated.data()); // 危险:会停在第一个'\0'
std::cout << "使用data()直接构造: \"" << str << "\" (长度: " << str.length() << ")" << std::endl;
// 正确处理包含null字符的vector
std::string safe_str(null_terminated.begin(), null_terminated.end());
std::cout << "使用迭代器安全构造: 长度 = " << safe_str.length()
<< ", 包含 " << std::count(safe_str.begin(), safe_str.end(), '\0')
<< " 个null字符" << std::endl;
}
// 性能测试示例
#include <chrono>
void performanceTest() {
const int SIZE = 1000000;
std::vector<char> large_vec(SIZE, 'x'); // 100万个'x'
auto start = std::chrono::high_resolution_clock::now();
std::string str(large_vec.begin(), large_vec.end());
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
std::cout << "\n性能测试 - 构造 " << SIZE << " 个字符的字符串:" << std::endl;
std::cout << "耗时: " << duration.count() << " 微秒" << std::endl;
std::cout << "字符串长度: " << str.length() << std::endl;
}
int main() {
testAllMethods();
// performanceTest();
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_4 chapter9_4.cpp
// 节练习 9.42(来自deepseek)
// chapter9_4.cpp
#include <iostream>
using namespace std;
string readCharsOptimized(int min_chars) {
string result;
result.reserve(min_chars); // 关键优化
char ch;
for (int i = 0; i < min_chars; ++i) {
ch = cin.get();
result.push_back(ch); // 高效追加
}
return result; // 可能启用返回值优化(RVO)
}
int main() {
readCharsOptimized(100);
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_4 chapter9_4.cpp
// 节练习 9.43
// chapter9_4.cpp
#include <iostream>
using namespace std;
void insert_and_erase(string s, string oldVal, string newVal)
{
string::iterator it = s.begin(); // 原字符串迭代器
size_t o_len = oldVal.size(); // 被替换字符串长度
size_t n_len = newVal.size(); // 新字符串长度
string word;
while (it != s.end() && (s.end() - it) >= o_len)
{
word.clear();
word.append(it, it + o_len);
// cout << "2 word is " << word<< endl;
if (word == oldVal)
{
it = s.erase(it, it + o_len); // 返回的迭代器指向删除的元素之后的元素(删除第一个"nihao"之后,返回迭代器在" "位置)
it = s.insert(it, newVal.begin(), newVal.end()); // 在当前迭代器之前插入元素,返回指向第一个插入字符的迭代器(添加"hello"之后,返回迭代器在h位置)
it = it + n_len;
// cout << "1 it is " << *it << endl;
}
else
{
it++;
}
}
cout << "result str is " << s << endl;
}
int main()
{
string str = "nihao good apple pear string pos low hign nihao name nihao";
string o_str = "nihao";
string n_str = "hello";
insert_and_erase(str, o_str, n_str);
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_4 chapter9_4.cpp
// 节练习 9.44
// chapter9_4.cpp
#include <iostream>
using namespace std;
void insert_and_erase(string s, string oldVal, string newVal)
{
size_t pos = 0; // 下标位置
size_t s_len = s.size(); // 原字符串长度
size_t o_len = oldVal.size(); // 被替换字符串长度
size_t n_len = newVal.size(); // 新字符串长度
string word;
while ((pos + o_len) < s_len)
{
word.clear();
word.append(s,pos,o_len);
// cout << "2 word is " << word<< endl;
if (word == oldVal)
{
s.replace(pos,o_len,newVal);
pos = pos + o_len;
// cout << "1 it is " << *it << endl;
}
else
{
pos ++;
}
}
cout << "2 result str is " << s << endl;
}
int main()
{
string str = "nihao good apple pear string pos low hign nihao name nihao";
string o_str = "nihao";
string n_str = "hello";
insert_and_erase(str, o_str, n_str);
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_4 chapter9_4.cpp
// 节练习 9.45
// chapter9_4.cpp
#include <iostream>
using namespace std;
string insert_and_append(string _name, string _pre, string _near)
{
string::iterator name_it = _name.begin();
name_it = _name.insert(name_it,_pre.begin(),_pre.end());
_name.append(_near);
return _name;
}
int main()
{
string name = "liuRY";
string pre = "Ms.";
string near = ".Jr";
cout << "result name is " << insert_and_append(name, pre, near)<< endl;
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_4 chapter9_4.cpp
// 节练习 9.46
// chapter9_4.cpp
#include <iostream>
using namespace std;
string insert_and_append(string _name, string _pre, string _near)
{
size_t name_len = _name.size();
size_t pre_len = _pre.size();
_name.insert(0,_pre);
_name.insert(name_len + pre_len,_near);
return _name;
}
int main()
{
string name = "liuRY";
string pre = "Ms.";
string near = ".Jr";
cout << "2 result name is " << insert_and_append(name, pre, near)<< endl;
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_4 chapter9_4.cpp
// 节练习 9.47
// chapter9_4.cpp
#include <iostream>
using namespace std;
int main()
{
string numbers("0123456789");
string str("ab3c3d7R4E60a");
size_t len = str.size();
size_t pos = 0;
while(pos < len) {
pos = str.find_first_of(numbers,pos); // pos = str.find_first_not_of(numbers,pos);
// cout << "pos_t = " << pos<< endl;
if (pos < len) {
cout << "data = " << str[pos]<< endl;
pos ++;
} else {
break;
}
}
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_4 chapter9_4.cpp
// 节练习 9.49
// chapter9_4.cpp
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
// string z1("acemnorsuvwxz");
string z2("bdfghijklpqty");
string str("transform proceed accc accelerate diminish fluctuate aa ambitious compassionate determined enthusiastic resilientalgorithm acc algorithm accccccccc blockchain cybersecurity database encryption");
string word;
string word_t;
size_t len = 0;;
size_t len_t = 0;
size_t pos = 0;
istringstream is(str);
while (is >> word_t)
{
len_t = word_t.size();
pos = word_t.find_first_of(z2);
if (pos >= len_t && len_t > len) { // 单词中不包含z2中的字符
len = len_t;
word.clear();
word.append(word_t);
}
}
cout << "word is " << word << ",len is " << len << endl;
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_4 chapter9_4.cpp
// 节练习 9.50(1)
// chapter9_4.cpp
#include <iostream>
#include <vector>
using namespace std;
int main()
{
// string z1("acemnorsuvwxz");
vector<string> v({"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20"});
vector<string>::iterator it = v.begin();
int sum = 0;
while (it != v.end())
{
int num = stoi(*it);
sum += num;
it ++;
}
cout << "sum is " << sum << endl;
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_4 chapter9_4.cpp
// 节练习 9.50(2)
// chapter9_4.cpp
#include <iostream>
#include <vector>
using namespace std;
int main()
{
// string z1("acemnorsuvwxz");
vector<string> v({"1.1","2.2","3.3","4.4","5.5","6.6","7.7","8.8","9.9","10.1","11.2","12.3","13.4","14.5","15.6","16.7","17.8","18.9","19.1","20.2"});
vector<string>::iterator it = v.begin();
float sum = 0;
while (it != v.end())
{
float num = stof(*it);
sum += num;
it ++;
}
cout << "sum is " << sum << endl;
return 0;
}
// 编译 g++ -std=c++11 -o chapter9_4 chapter9_4.cpp
// 节练习 9.51(deepseek 生成)
// chapter9_4.h
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <sstream>
#include <cctype>
#include <stdexcept>
#include <algorithm>
class Date {
private:
unsigned year;
unsigned month;
unsigned day;
// 月份名称映射
static std::map<std::string, unsigned> monthMap;
static bool mapsInitialized;
// 初始化月份映射
static void initializeMaps() {
if (mapsInitialized) return;
// 完整月份名
monthMap["january"] = 1;
monthMap["february"] = 2;
monthMap["march"] = 3;
monthMap["april"] = 4;
monthMap["may"] = 5;
monthMap["june"] = 6;
monthMap["july"] = 7;
monthMap["august"] = 8;
monthMap["september"] = 9;
monthMap["october"] = 10;
monthMap["november"] = 11;
monthMap["december"] = 12;
// 缩写月份名
monthMap["jan"] = 1;
monthMap["feb"] = 2;
monthMap["mar"] = 3;
monthMap["apr"] = 4;
monthMap["may"] = 5;
monthMap["jun"] = 6;
monthMap["jul"] = 7;
monthMap["aug"] = 8;
monthMap["sep"] = 9;
monthMap["oct"] = 10;
monthMap["nov"] = 11;
monthMap["dec"] = 12;
mapsInitialized = true;
}
// 辅助函数:转换为小写
static std::string toLower(const std::string& str) {
std::string result = str;
std::transform(result.begin(), result.end(), result.begin(),
[](unsigned char c) { return std::tolower(c); });
return result;
}
// 辅助函数:去除字符串两端的空白字符
static std::string trim(const std::string& str) {
size_t first = str.find_first_not_of(" \t\n\r");
if (first == std::string::npos) return "";
size_t last = str.find_last_not_of(" \t\n\r");
return str.substr(first, last - first + 1);
}
// 辅助函数:分割字符串
static std::vector<std::string> split(const std::string& str, char delimiter) {
std::vector<std::string> tokens;
std::string token;
std::istringstream tokenStream(str);
while (std::getline(tokenStream, token, delimiter)) {
token = trim(token);
if (!token.empty()) {
tokens.push_back(token);
}
}
return tokens;
}
// 验证日期是否有效
bool isValidDate(unsigned y, unsigned m, unsigned d) {
if (m < 1 || m > 12) return false;
if (d < 1 || d > 31) return false;
// 检查月份天数
int daysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 闰年处理
if (m == 2) {
bool isLeapYear = (y % 400 == 0) || (y % 4 == 0 && y % 100 != 0);
if (isLeapYear) daysInMonth[1] = 29;
}
return d <= daysInMonth[m - 1];
}
// 设置日期
void setDate(unsigned y, unsigned m, unsigned d) {
if (!isValidDate(y, m, d)) {
throw std::invalid_argument("Invalid date");
}
year = y;
month = m;
day = d;
}
// 解析数字格式的日期 (MM/DD/YYYY 或 YYYY-MM-DD 等)
bool parseNumericFormat(const std::string& dateStr) {
std::string cleaned = dateStr;
// 替换可能的日期分隔符为空格
std::replace_if(cleaned.begin(), cleaned.end(),
[](char c) { return c == '/' || c == '-' || c == '.' || c == ','; }, ' ');
auto tokens = split(cleaned, ' ');
if (tokens.size() != 3) return false;
unsigned m, d, y;
try {
// 尝试格式 MM/DD/YYYY 或 DD/MM/YYYY
m = std::stoul(tokens[0]);
d = std::stoul(tokens[1]);
y = std::stoul(tokens[2]);
// 检查年份是否为2位数(假设是1900-1999)
if (y < 100) {
y += 1900; // 可以根据需求调整这个逻辑
}
// 尝试两种可能的顺序
if (isValidDate(y, m, d)) {
setDate(y, m, d);
return true;
}
// 尝试交换月和日
if (isValidDate(y, d, m)) {
setDate(y, d, m);
return true;
}
} catch (const std::exception&) {
return false;
}
return false;
}
// 解析月份名称格式的日期
bool parseMonthNameFormat(const std::string& dateStr) {
auto tokens = split(dateStr, ' ');
if (tokens.size() < 3) return false;
std::string monthStr = toLower(tokens[0]);
std::string dayStr = tokens[1];
std::string yearStr = tokens[2];
// 处理日期中的逗号 (如 "January 1, 1900")
if (dayStr.back() == ',') {
dayStr = dayStr.substr(0, dayStr.length() - 1);
}
// 如果第二部分是逗号,调整token索引
if (tokens.size() > 3 && tokens[1] == ",") {
monthStr = toLower(tokens[0]);
dayStr = tokens[2];
yearStr = tokens[3];
}
// 查找月份
auto it = monthMap.find(monthStr);
if (it == monthMap.end()) return false;
try {
unsigned m = it->second;
unsigned d = std::stoul(dayStr);
unsigned y = std::stoul(yearStr);
// 处理2位数年份
if (y < 100) {
y += 1900;
}
if (isValidDate(y, m, d)) {
setDate(y, m, d);
return true;
}
} catch (const std::exception&) {
return false;
}
return false;
}
public:
// 默认构造函数
Date() : year(1900), month(1), day(1) {
initializeMaps();
}
// 主要构造函数
Date(const std::string& dateStr) {
initializeMaps();
if (dateStr.empty()) {
throw std::invalid_argument("Date string cannot be empty");
}
std::string trimmed = trim(dateStr);
// 尝试月份名称格式
if (parseMonthNameFormat(trimmed)) {
return;
}
// 尝试数字格式
if (parseNumericFormat(trimmed)) {
return;
}
throw std::invalid_argument("Unable to parse date string: " + dateStr);
}
// 带参数的构造函数
Date(unsigned y, unsigned m, unsigned d) {
setDate(y, m, d);
}
// 获取器
unsigned getYear() const { return year; }
unsigned getMonth() const { return month; }
unsigned getDay() const { return day; }
// 格式化输出
std::string toString() const {
std::ostringstream oss;
oss << year << "-"
<< (month < 10 ? "0" : "") << month << "-"
<< (day < 10 ? "0" : "") << day;
return oss.str();
}
// 友元输出操作符
friend std::ostream& operator<<(std::ostream& os, const Date& date) {
os << date.toString();
return os;
}
};
// chapter9_4.cpp
#include "chapter9_4.h"
// 静态成员初始化
std::map<std::string, unsigned> Date::monthMap;
bool Date::mapsInitialized = false;
// 测试函数
int main() {
try {
// 测试不同的日期格式
std::vector<std::string> testDates = {
"January 1, 1900",
"1/1/1990",
"Jan 1 1900",
"1990-01-01",
"12/25/2023",
"December 25, 2023",
"25.12.2023",
"Feb 28, 2020", // 闰年
"March 15, 2000",
"7/4/1776"
};
std::cout << "Testing Date class with various formats:\n";
std::cout << "=========================================\n";
for (const auto& dateStr : testDates) {
try {
Date date(dateStr);
std::cout << "Original: \"" << dateStr << "\"\n";
std::cout << "Parsed: " << date.toString() << "\n";
std::cout << "Components: Year=" << date.getYear()
<< ", Month=" << date.getMonth()
<< ", Day=" << date.getDay() << "\n";
std::cout << "---\n";
} catch (const std::exception& e) {
std::cout << "Error parsing \"" << dateStr << "\": "
<< e.what() << "\n";
std::cout << "---\n";
}
}
// 测试无效日期
std::cout << "\nTesting invalid dates:\n";
std::cout << "======================\n";
std::vector<std::string> invalidDates = {
"February 30, 2023", // 无效日期
"13/1/2023", // 无效月份
"January 32, 2023", // 无效日期
"Not a date", // 无效格式
"Jan/1/2023" // 混合格式
};
for (const auto& dateStr : invalidDates) {
try {
Date date(dateStr);
std::cout << "Unexpectedly parsed: \"" << dateStr << "\" as "
<< date.toString() << "\n";
} catch (const std::exception& e) {
std::cout << "Correctly rejected \"" << dateStr << "\": "
<< e.what() << "\n";
}
}
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}
编译: g++ -std=c++11 -o chapter9_4 chapter9_4.cpp
// 节练习 9.52
没看明白题。