如何以固定大小数组作为map键向其中插入字符串?
问题:用std::array作为map的键实现字母异位词分组
我尝试用std::array<int,26>作为map的键来分组字母异位词,但运行报错。注释掉的代码是用vector<int>作为键的实现,那部分能正常运行,现在想改用固定大小数组解决,求正确实现方式。
报错代码
class Solution { public: vector<vector<string>> groupAnagrams(vector<string>& strs) { vector<vector<string>> res; map<array<int,26>,vector<string>> keys; // map<vector<int>,vector<string>> keys; // 这行用vector的实现可正常运行 for(auto x:strs){ int count[26]; // vector<int> count(26,0); for(auto c:x){ count[c-'a']++; } keys[count].emplace_back(x); } for(auto k = keys.begin(); k != keys.end(); k++){ res.emplace_back(k->second); } return res; } };
运行错误信息
第13行第17列:错误:类型为'map<array<int, 26>, vector<std::string>>'(别名'map<array<int, 26>, vector<basic_string<char>>>')的对象没有可行的重载operator[] keys[count].emplace_back(x); ~~~~^~~~~~ /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_map.h:490:7: 注意:候选函数不可行:无法将'int [26]'转换为const键类型(即'const std::array<int, 26>')作为第一个参数 operator[](const key_type& __k) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_map.h:510:7: 注意:候选函数不可行:无法将'int [26]'转换为键类型(即'std::array<int, 26>')作为第一个参数 operator[](key_type&& __k) ^ 生成1个错误。
解决方法
核心问题是C风格数组和std::array是完全不同的类型:你定义的map键是std::array<int,26>,但传入的count是int[26],两者无法隐式转换;而且C风格数组会退化为指针,根本不能作为map的有效键(map会按指针地址而非数组内容比较)。
修正后的代码如下:
#include <array> // 必须包含std::array的头文件 class Solution { public: vector<vector<string>> groupAnagrams(vector<string>& strs) { vector<vector<string>> res; map<array<int,26>,vector<string>> keys; for(auto& str : strs){ // 用引用避免字符串拷贝,提升效率 array<int,26> count{}; // 大括号初始化,自动将所有元素置为0 for(char c : str){ count[c - 'a']++; } keys[count].emplace_back(str); } // 用范围for循环遍历map,写法更简洁 for(auto& entry : keys){ res.emplace_back(entry.second); } return res; } };
关键说明
std::array是C++11引入的固定大小容器,属于完整的类类型,天然支持<运算符重载,符合map对键的排序要求;array<int,26> count{}的初始化方式会把所有元素默认置为0,避免了C风格数组未初始化导致的垃圾值问题;- 使用引用遍历字符串和map元素,减少不必要的拷贝操作,优化性能。
内容的提问来源于stack exchange,提问作者Puchor
相关产品推荐
相关产品推荐

