7.1 vector 与迭代器
答:______________
✅ 查看答案与解析
答案 对
解析:map 底层是红黑树,迭代按键的有序顺序。
答:______________
✅ 查看答案与解析
答案 对
解析:m[\"apple\"] 若键不存在,会插入 0(对 int)再返回引用。所以用它判断键存在会悄悄改变容器大小。
把元素个数设为 10
预分配能放 10 个元素的空间,避免前 10 次 push_back 扩容
清空 v
把 v 变成定长数组
答:______________
✅ 查看答案与解析
答案 B
解析:find 返回迭代器(找不到返回 end()),count 返回 0 或 1。operator[] 会误插入,at() 找不到会抛异常。
std::vector<int> v{1, 2, 3};
int* p = v.data();
v.push_back(4); // 可能扩容,p 变成悬垂指针
std::cout << *p; // 未定义行为
✅ 查看答案与解析
答案 if (m.count("b") != 0) { std::cout << "exists"; }
解析:查询用 find/count,别用 operator[]。
提示:遍历用范围 for (int x : v)。
✅ 查看答案与解析
答案 参考答案:
解析:++freq[word] 是统计频率的经典写法:不存在则插入 0 再自增。结构化绑定解包 pair。
#include <iostream>
#include <map>
#include <string>
int main() {
std::map<std::string, int> freq;
std::string word;
while (std::cin >> word) { ++freq[word]; }
for (const auto& [key, value] : freq) {
std::cout << key << ' ' << value << '\n';
}
return 0;
}7.2 关联容器 map / set
答:______________
✅ 查看答案与解析 (本站补充)
答案 对。
解析:map 底层是红黑树,按键严格弱序排列;用迭代器或范围 for 遍历都是按键升序。想按插入顺序遍历要额外记录 key 的顺序。
答:______________
✅ 查看答案与解析 (本站补充)
答案 对。
解析:m[k] 在键不存在时会插入一个值初始化的元素(int 为 0)再返回引用,所以“查询”会改变容器大小;只查不写请用 find / count。
m[key] 判断是否非零
m.find(key) 或 m.count(key)
m.at(key)
遍历所有键
答:______________
✅ 查看答案与解析 (本站补充)
答案 答案:B(m.count(key))。
解析:count 返回 0 或 1 且不修改容器;C++20 起还可以用 contains。A 的 m[key] 会插入默认值,D 的 m.find(key) 需要再判断是否为 end(),多一步但也可用。
std::map<std::string, int> m{{"a", 1}};
if (m["b"] != 0) { std::cout << "exists"; }
// 判断 m 里有没有 "b":没有,但 m["b"] 已经插入了 {b:0}
✅ 查看答案与解析 (本站补充)
答案 答案:把 if (m[key] == 0) 改成 if (m.count(key) == 0)。
解析:operator[] 在键不存在时会插入默认构造的值(int 为 0),于是“查询”变成了插入,容器被污染。查询用 count / find / contains,确定要写入时才用 []。
提示:读取到文件结束:while (std::cin >> word)。
✅ 查看答案与解析 (本站补充)
答案 参考答案:
#include <iostream>
#include <map>
#include <string>
int main() {
std::map<std::string, int> freq;
std::string w;
while (std::cin >> w) {
++freq[w]; // 不存在就插入 0 再自增
}
for (const auto& [word, cnt] : freq) { // map 自动按键升序
std::cout << word << ' ' << cnt << '\n';
}
return 0;
}
解析:++freq[w] 是统计频率的经典写法;遍历 map 得到的就是字典序,不需要额外排序。
7.3 迭代器失效与容器选型
答:______________
✅ 查看答案与解析
答案 对
解析:所以循环里删除元素要写 it = v.erase(it); 并接住返回值。
list 的算法复杂度更高
链表节点分散在内存各处,缓存命中率极低
list 不能随机访问
list 不支持范围 for
答:______________
✅ 查看答案与解析
答案 B
解析:链表每次访问都要跳指针,CPU 缓存极不友好;vector 连续内存,实际常数小得多。工程里优先 vector。
小顶堆
大顶堆
无序数组
平衡树
答:______________
✅ 查看答案与解析
答案 B
解析:C++ 默认最大堆(top() 是最大值),和 Java 默认最小堆相反。要小顶堆写 std::priority_queue<int, std::vector<int>, std::greater<int>>。
for (auto it = v.begin(); it != v.end(); ++it) {
if (*it % 2 == 0) { v.erase(it); } // it 已失效,还继续 ++it
}
✅ 查看答案与解析
答案 for (auto it = v.begin(); it != v.end(); ) {
解析:erase 返回下一个有效迭代器,接住它;只有没删除时才手动 ++it。
if (*it % 2 == 0) { it = v.erase(it); }
else { ++it; }
}提示:默认大顶堆,pop 三次即可。
✅ 查看答案与解析
答案 参考答案:
解析:priority_queue 的 top() 是 O(1),push/pop 是 O(log n)。
#include <iostream>
#include <queue>
int main() {
int n;
std::cin >> n;
std::priority_queue<int> pq;
for (int i = 0; i < n; ++i) { int x; std::cin >> x; pq.push(x); }
for (int i = 0; i < 3 && !pq.empty(); ++i) {
std::cout << pq.top() << ' ';
pq.pop();
}
std::cout << '\n';
return 0;
}