You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Signature与AnagramMap类移入自定义C++命名空间

实现步骤与代码示例

要将Signature和AnagramMap移入foo命名空间、保留Solution在全局空间,只需按以下结构调整代码:

1. 用自定义命名空间包裹目标类

直接将Signature和AnagramMap的定义放入foo命名空间中,类内部逻辑保持不变。若需在命名空间外定义成员函数,需添加foo::前缀。

2. 正确特化std::hash<foo::Signature>

由于要特化标准库的std::hash模板,必须将特化代码放在std命名空间内。同时为让哈希函数能访问Signature的私有成员(如字符频率数组),需在Signature类中声明std::hash<foo::Signature>为友元。

3. 全局Solution类引用命名空间内的类

在Solution的成员函数中,通过foo::前缀调用AnagramMap或Signature,确保编译器能定位到命名空间内的类型。

完整代码示例

#include <vector>
#include <string>
#include <unordered_map>
#include <array>

// 自定义命名空间foo,包含Signature和AnagramMap
namespace foo {
    class Signature {
    private:
        std::array<int, 26> counts{};
        // 声明std::hash为友元,允许其访问私有成员counts
        friend struct std::hash<foo::Signature>;
    public:
        Signature(const std::string& s) {
            for (char c : s) {
                counts[c - 'a']++;
            }
        }

        // 重载==运算符,用于unordered_map的键值比较
        bool operator==(const Signature& other) const {
            return counts == other.counts;
        }
    };

    class AnagramMap {
    private:
        std::unordered_map<Signature, std::vector<std::string>> map;
    public:
        void add(const std::string& s) {
            map[Signature(s)].push_back(s);
        }

        std::vector<std::vector<std::string>> getGroups() {
            std::vector<std::vector<std::string>> result;
            for (auto& pair : map) {
                result.push_back(std::move(pair.second));
            }
            return result;
        }
    };
}

// 在std命名空间内特化hash模板,适配foo::Signature
namespace std {
    template<>
    struct hash<foo::Signature> {
        size_t operator()(const foo::Signature& sig) const {
            size_t hash_val = 0;
            // 基于字符频率数组计算哈希值
            for (int count : sig.counts) {
                hash_val = hash_val * 31 + count;
            }
            return hash_val;
        }
    };
}

// Solution类保留在全局命名空间
class Solution {
public:
    std::vector<std::vector<std::string>> groupAnagrams(std::vector<std::string>& strs) {
        foo::AnagramMap anagramMap;
        for (const std::string& s : strs) {
            anagramMap.add(s);
        }
        return anagramMap.getGroups();
    }
};

关键注意事项

  • 友元声明:必须在Signature中声明std::hash<foo::Signature>为友元,否则哈希函数无法访问私有成员counts,会触发编译错误。
  • 命名空间前缀:全局空间的代码(如Solution)引用foo内的类时,必须添加foo::前缀,避免命名冲突或编译时找不到类型。
  • std模板特化规则:特化标准库模板必须放在std命名空间内,这是C++标准的强制要求,否则特化不会生效。

内容的提问来源于stack exchange,提问作者IRP_HANDLER

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 04:24:57