赞
踩
(a)读取固定数量的单词,将它们按字典序插入到容器中
(b) 读取未知数量的单词,总是将新单词插入到末尾。删除在头部进行
© 从一个文件读取未知数量的整数。将这些数排序,然后将它们打印到标准输出
(a)适合用list,因为按字典序插入到容器中,很多情况是插入到原序列的中间位置,list在任何位置插入/删除的速度较快。
(b)适合于用deque(双端队列),因为一个标准的单端队列就是头删尾插,故执行该操作速度很快。
©适合用vector,因为读取的时候都往尾部插入即可,vector尾插效率是常数的时间复杂度,并且vector支持随机访问,进行排序也更为方便高效
begin和end迭代器需要满足:
vector::size_type
begin根据调用该函数的容器对象是否为常数返回const_iterator或者iterator
cbegin返回const_iterator
vector<int> v1;
const vector<int> v2;
auto it1 = v1.begin(); //vector<int>::iterator
auto it2 = v2.begin(); // vector<int>::const_iterator
auto it3 = v1.cbegin(); //vector<int>::const_iterator
auto it4 = v2.cbegin(); //vector<int>::const_iterator
接受一个容器创建其拷贝的拷贝构造函数,要求容器的类型及元素类型都要一直
接受两个迭代器创建拷贝范围的构造函数只需要元素的类型能够转换即可
if(c1 < c2)
首先要满足c1和c2的容器类型相同,且存放的元素类型相同,其次存放的元素类型也有提供 < 运算符
void p9_20() { list<int> l{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; deque<int> dq1; deque<int> dq2; for (const int& n : l) { //巧用位运算 (n & 0x1 ? dq1 : dq2).push_back(n); } for (const int& n : dq1) cout << n << " "; cout << endl; for (const int& n : dq2) cout << n << " "; cout << endl; }
vector<int>::iterator iter = iv.begin(), mid = iv.begin() + iv.size() / 2;
while (iter != mid)
if (*iter == some_val)
iv.insert(iter, 2 * some_val);
如果*iter != some_val,且iter又不会改变,则会陷入死循环;其次迭代器可能会失效,应该修改为
vector<int>::iterator iter = iv.begin(), mid = iv.begin() + iv.size() / 2;
while (iter != mid)
{
if (*iter++ == some_val)
{
iter = iv.insert(iter, 2 * some_val);
++iter; // 让iter恢复到原来的位置上
}
++iter; //iter向前移动一步,防止死循环
}
vec.resize(100)添加75个元素0,从末尾删除90个元素,最后剩下最开始前10个元素。
如果容器保存的是类类型元素,且resize向容器添加新元素,则我们必须提供初始值,或者元素类型必须提供一个默认构造函数
对于list和forwardlist来说,不支持迭代器的+=,+运算符。对于forward_list不支持insert和erase,只支持insert_after和erase_after,修改为:
void p9_31() { //删除偶数元素,复制每个奇数元素 list<int> li = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; //forward_list<int> li = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; auto iter = li.begin(); while (iter != li.end()) { if (*iter % 2) { iter = li.insert(iter, *iter);//复制当前元素,插入到iter之前的位置,返回指向新插入的元素的位置的迭代器 iter++; iter++; } else { iter = li.erase(iter);//删除偶数元素 } } for (int n : li) cout << n << " "; cout << endl; }
void p9_31_1() { //删除偶数元素,复制每个奇数元素 //list<int> li = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; forward_list<int> li = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; auto iter = li.begin(); auto prev = li.before_begin();//首前迭代器 while (iter != li.end()) { if (*iter % 2) { li.insert_after(prev, *iter);//复制当前元素,插入到prev之后的位置,返回指向新插入的元素的位置的迭代器 prev = iter; ++iter; } else { iter = li.erase_after(prev);//删除偶数元素,返回被删除元素之后的迭代器 } } for (int n : li) cout << n << " "; cout << endl; }
iter = vi.insert(iter, *iter++);
不合法,同一个表达式中不应该使用修改过的子表达式,因为求值顺序不定,导致表达式未定义
vector<int> vi{ 1, 2, 3 };
vector<int>::iterator begin = vi.begin();
while (begin != vi.end())
{
++begin;//向前移动begin,我们想在此元素之后插入元素
begin = vi.insert(begin, 42); //begin迭代器失效
++begin;
}
for (int n : vi)
cout << n << " ";
cout << endl;
插入元素后的迭代器失效即begin会失效,抛出异常
capacity表示在不重新分配内存空间的情况下vector可存放元素的大小,size表示vector已经存放元素的个数
因为list是实时分配的空间的,插入一个元素就分配一个空间,不会提前预留空间,没必要用一个capacity表示容量
array容器大小是固定的只用一个size()表示即可
在vs2019中提供的编译器,每次增长原来容量的一半,即当前capacity() = size()为50,再插入一个元素后capacity变为75
vector<string> svec;
svec.reserve(1024); // 分配至少能容纳1024个元素的空间
string word;
while (cin >> word)
svec.push_back(word);
svec.resize(svec.size() + svec.size()/2); //改变容器的size大小,新加入的元素默认初始化为空串
读入256个词,capacity为1024
读入512个词,capacity为1024
读入1000个词,resize后size为1500,capacity为1536,
读入1048个词,resize后size为1572,capacity为2304
为string预留至少100个字符大小的空间如
string s;
s.reserve(128);
方法一:
//判断以字符串s的ps位置开始是否有与字符串s2匹配 bool find(const string &s, string::const_iterator ps, const string& s2) { for (string::const_iterator cit = s2.begin(); cit != s2.end(); ++ps, ++cit) { if (ps == s.cend() || *ps != *cit) return false; } return true; } void p9_43_1(string& s, const string& oldVal, const string& newVal) { string::iterator it = s.begin(); while (it != s.end()) { if (find(s, it, oldVal)) { //返回删除区间段最后一个位置的下一个位置的迭代器 it = s.erase(it, it + oldVal.size()); //返回插入区间第一个位置的迭代器 it = s.insert(it, newVal.begin(), newVal.end()); it += newVal.size(); } else ++it; } } void test02() { string str = "dskthruid ththruid"; p9_43_1(str, "thru", "through"); cout << str << endl; }
方法二:
void p9_43(string &s,const string &oldVal, const string &newVal) { //替换 = 删除+插入 string::iterator curr = s.begin(); while (curr <= s.end() - oldVal.size()) { //检测当前位置开始是否有满足条件的字符串 if (oldVal == string(curr, curr + oldVal.size())) { //erase(pos,len) curr = s.erase(curr, curr + oldVal.size()); //insert(pos, args) curr = s.insert(curr, newVal.begin(), newVal.end()); curr += newVal.size(); } else ++curr; } cout << s << endl; }
void p9_44(string& s, const string& oldVal, const string& newVal) { //判断的位置pos,最大到s.size()-oldVal.size();,再往后没有足够长的字符了 for (size_t pos = 0; pos <= s.size() - oldVal.size(); ) { //利用短路求值特性,如果第一个判断式不满足就不用在执行右边的判断了 if (s[pos] == oldVal[0] && s.substr(pos, oldVal.size()) == oldVal) { //将s从pos位置开始的oldVal.size()个元素替换为newVal s.replace(pos, oldVal.size(), newVal); pos += newVal.size(); } else ++pos; } }
text49.txt
Description of the most important classes, functions and objects of the Standard Language Library, with descriptive fully-functional short programs as examples:
void find_no_head(const string& s, string &result) { string head("dfpg"); //若单词s中没有出头的字母 if (s.find_first_of(head) == string::npos) { result = s.size() > result.size() ? s : result; } } void p9_49() { ifstream ifs("text49.txt"); string line; string longest , word; //对每个单词进行判断有无出头字母 //并且对含无出头字母的单词比较长度 while (ifs >> word) { find_no_head(word, longest); } //while (getline(ifs, line)) //{ // istringstream ifs(line);//创建一个字符串输入流,用line初始化 // // while (ifs >> word) // { // find_no_head(word, longest); // } //} cout << longest << endl; }
#include<iostream> #include<string> #include<vector> using std::string; using std::vector; using std::cin; using std::cout; using std::endl; class Date { public: Date(string date); void print() { cout << "day: " << day << " " << "month: " << month << " " << "year: " << year << endl; } private: void convert1(const string& s); void convert2(const string& s); void convert3(const string& s); void convert_month(const string& s); unsigned year; unsigned month; unsigned day; }; Date::Date(string date) { if (date.find_first_of("/") != string::npos) convert1(date); else if (date.find_first_of(",") != string::npos) convert2(date); else if (date.find_first_of(" ") != string::npos) convert3(date); else year = 1900, month = 1, day = 1; } void Date::convert1(const string& s) { month = stoi(s.substr(0, s.find_first_of("/"))); day = stoi(s.substr(s.find_first_of("/") + 1, s.find_last_of("/") - s.find_first_of("/") - 1)); year = stoi(s.substr(s.find_last_of("/") + 1, 4)); } void Date::convert2(const string& s) { convert_month(s); day = stoi(s.substr(s.find_first_of("123456789"), s.find_first_of(",") - s.find_first_of("123456789"))); year = stoi(s.substr(s.find_last_of(" ") + 1, 4)); } void Date::convert3(const string& s) { convert_month(s); day = stoi(s.substr(s.find_first_of("123456789"), s.find_last_of(" ") - s.find_first_of("123456789"))); year = stoi(s.substr(s.find_last_of(" ") + 1, 4)); } void Date::convert_month(const string& s) { if (s.find("Jan") != string::npos) month = 1; else if (s.find("Feb") != string::npos) month = 2; else if (s.find("Mar") != string::npos) month = 3; else if (s.find("Apr") != string::npos) month = 4; else if (s.find("May") != string::npos) month = 5; else if (s.find("Jun") != string::npos) month = 6; else if (s.find("Jul") != string::npos) month = 7; else if (s.find("Aug") != string::npos) month = 8; else if (s.find("Sept") != string::npos) month = 9; else if (s.find("Oct") != string::npos) month = 10; else if (s.find("Nov") != string::npos) month = 11; else if (s.find("Dec") != string::npos) month = 12; }
测试代码
void test01()
{
Date d1("March 13, 1998");
Date d2("3/13/1998");
Date d3("Mar 13 1998");
d1.print();
d2.print();
d3.print();
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。