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

如何创建支持char或string的map/unordered_map模板并适配排序打印函数

解决C++模板函数适配不同Map类型的问题

问题场景

编写程序读取指定TXT文件,统计文本中字符(char)和单词(string)的出现频率,分别存入map或unordered_map(键为char/string,值为int),再按频率排序后存入vector并打印。原本分开编写字符和单词的统计、打印函数时运行正常,但将排序打印函数改写为模板以适配两种类型时,编译报错:

error: no matching function for call to ‘print_frequencies_sorted(std::map<char, int>&)’

即便直接传递对应类型的map引用也无法解决,核心是模板函数无法适配不同类型的map。

错误根源

  • 模板参数无法推导:原函数模板同时声明了Map和typ两个参数,调用时编译器无法自动推导typ的类型;
  • Vector声明错误:原代码中用vector<typ, int>来存储键值对,正确写法应为vector<typename Map::value_type>,因为Map的value_type本身就是键值对类型(比如pair<const char, int>)。

修复方案

简化模板参数

只保留Map作为模板参数,通过Map的嵌套类型获取键、值和键值对类型,无需额外的typ参数。

修正Vector与排序逻辑

用typename Map::value_type定义vector的元素类型,排序时通过pair的second成员(即频率值)进行比较。

修复后的代码示例

#include <iostream>
#include <fstream>
#include <map>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <string>

// 模板化的排序打印函数,适配任意键类型的map/unordered_map
template <typename Map>
void print_frequencies_sorted(Map& freq_map) {
    // 将map的键值对存入vector
    std::vector<typename Map::value_type> freq_vec(freq_map.begin(), freq_map.end());
    
    // 按频率降序排序,频率相同则按键升序(可选)
    std::sort(freq_vec.begin(), freq_vec.end(),
        [](const typename Map::value_type& a, const typename Map::value_type& b) {
            if (a.second != b.second) {
                return a.second > b.second;
            }
            return a.first < b.first;
        });
    
    // 打印结果
    for (const auto& item : freq_vec) {
        std::cout << "[" << item.first << "] : " << item.second << std::endl;
    }
}

// 统计字符频率
void count_characters(const std::string& filename, std::map<char, int>& char_freq) {
    std::ifstream file(filename);
    char c;
    while (file.get(c)) {
        char_freq[c]++;
    }
}

// 统计单词频率(简单分割,按空白字符分割)
void count_words(const std::string& filename, std::unordered_map<std::string, int>& word_freq) {
    std::ifstream file(filename);
    std::string word;
    while (file >> word) {
        word_freq[word]++;
    }
}

int main() {
    std::map<char, int> char_freq;
    std::unordered_map<std::string, int> word_freq;
    
    count_characters("test.txt", char_freq);
    count_words("test.txt", word_freq);
    
    std::cout << "字符频率(按频率排序):" << std::endl;
    print_frequencies_sorted(char_freq);
    
    std::cout << "\n单词频率(按频率排序):" << std::endl;
    print_frequencies_sorted(word_freq);
    
    return 0;
}

关键说明

  • 模板函数print_frequencies_sorted仅需一个Map参数,编译器可自动推导传入的map或unordered_map类型;
  • 使用typename Map::value_type确保能正确获取键值对类型,避免硬编码;
  • 排序Lambda函数可灵活调整排序规则,示例中优先按频率降序,频率相同时按键升序。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 19:52:26