加深印象用,使用primer中的综合例子(习题)做回顾,不会列出所有知识点细节,只列出常用的。
1. 顺序容器
1.1迭代器
迭代器是一种抽象的设计概念,在设计模式中iterator模式被定义为:提供一种方法,可以按序访问某一聚合物(容器)所含元素,且不暴露该聚合物的内部表达方式。
可以简化的理解为一个指针(但不是),可访问容器中不同位置的元素,需要注意的是迭代器范围为[begin,end),end为尾元素的后一个位置。
习题9.4:判断容器中是否有要查找的值
bool find_int(vector<int>::const_iterator begin, vector<int>::const_iterator end, int n)
{
while (begin != end)
{
if (*begin == n) return true;
++begin;
}
return false;
}
int main()
{
vector<int> vi{ 1,2,3,4,5,6 };
cout << boolalpha << find_int(vi.begin(), vi.end(), 2) << endl;
return 0;
}
1.2迭代器的重新定位
对于非链表类型(list)的容器,由于其元素空间连续,因此增加删除元素会改变原有迭代器的指向,导致原有迭代器失效,需要重新定位。
习题9.33:在每个元素后添加新元素
int main()
{
vector<int> v1 = {0,1,2,3,4,5,6,7,8,9};
auto iter = v1.begin();
while(iter != v1.end())
{
++iter;//第一次循环迭代器指向1
iter = v1.insert(iter, 42);//当前为0 42 1 2 。。。并指向42
++iter;//迭代器指向1
}
for(const auto i : v1)
cout << i << " ";
cout << endl;
return 0;
}
1.3 容器适配器
queue:先进先出;
stack:先进后出;
队列:
int main()
{
string expression{ "This is (abcd)." };
bool bSeen = false;
queue<char> stk;
for (const auto& s : expression)
{
if (s == '(') { bSeen = true; continue; }
else if (s == ')') bSeen = false;
if (bSeen) stk.push(s);
}
string repstr;
while (!stk.empty())
{
repstr += stk.front();
stk.pop();
}
expression.replace(expression.find("(") + 1, repstr.size(), repstr);
cout << expression << endl;
return 0;
}
输出结果:
This is (abcd).
stack:
int main()
{
string expression{ "This is (abcd)." };
bool bSeen = false;
stack<char> stk;
for (const auto& s : expression)
{
if (s == '(') { bSeen = true; continue; }
else if (s == ')') bSeen = false;
if (bSeen) stk.push(s);
}
string repstr;
while (!stk.empty())
{
repstr += stk.top();
stk.pop();
}
expression.replace(expression.find("(") + 1, repstr.size(), repstr);
cout << expression << endl;
return 0;
}
输出结果:
This is (dcba).
2. 关联容器
2.1 迭代器
map迭代器为pair<const key,value>,可改变value,但不能改变key(const);
set迭代器为 const key,不可改变;
习题11.31
int main()
{
std::multimap<std::string, std::string> m1 = { {"aa", "abc"}, {"bb", "bcd"}, {"cc", "cde"} };
if (m1.find("aa") != m1.end())
{
m1.erase(m1.find("aa"));
}
else
{
cout << "未找到元素" << endl;
}
for (const auto& p : m1)
std::cout << p.first << " " << p.second << std::endl;
return 0;
}
输出结果:
bb bcd
cc cde
2.2 综合练习:
习题11.33:单词转换程序,规则:在被转换的文本中发现缩写时,则根据规则将缩写转换成短语;共输入两个文件,一个文件存储规则,另一个文件存储需要被转换的文本。
规则:
brb be right back
k okay:
y why
r are
u you
pic picture
thk thanks!
18r later
希望转换的文本:
where r u
y dont u send me a pic
k thk 18r
希望得到的结果:
where are you
why dont you send me a picture
okay? thanks! later
需求分析:
1、将规则文件中的缩写与短语读入,形成map,缩写为key,短语为value;
2、读入需要转换得到文本,如果在map中到当前字符串key,则替换为value,否则返回原字符串。
//实现需求1:
map<string, string>buildMap(ifstream& map_file)
{
map<string, string> trans_map;
string key;
string value;
//第一个单词写入key,剩余内容写入value
while (map_file >> key && getline(map_file, value))
{
if (value.size() > 1)
trans_map[key] = value.substr(1);
else
throw runtime_error("no rule for"+key);
}
return trans_map;
}
//实现需求2:
const string& transform(const string&s,const map<string,string> &m)
{
auto map_it = m.find(s);
if (map_it != m.cend())
return map_it->second;
else
return s;
}
void word_transform(ifstream&map_file,ifstream&input)
{
auto trans_map = buildMap(map_file);
string text;
while (getline(input, text))//读取一行
{
istringstream stream(text);//遇到空格结束,读取每个单词
string word;
bool firstword = true;
while (stream >> word)
{
if (firstword)
firstword = false;
else
cout << " ";
cout << transform(word, trans_map);
}
cout << endl;
}
}
int main()
{
ifstream map_file("regular.txt"), input("input.txt");
word_transform(map_file, input);
return 0;
}
2.3 无序容器
暂时用的不多,对自定义的类使用无序容器需要重载哈希函数:
hash<内置类型>()(自定义类中的一个对象);