news 2026/8/22 17:29:58

【map应用】组合键统计

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【map应用】组合键统计

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 一、概述
      • 实现的关键逻辑
      • 示例场景(以Python为例)
  • 二、组合统计
      • 代码说明:
      • 输出结果:
  • 三、单属性统计
      • 代码说明:
      • 输出结果:
  • 四、说明一
      • 具体说明:
      • 代码示例验证:
      • 总结:
  • 五、说明二
      • 核心排序逻辑:先比第一个元素,再比第二个元素
      • 举例说明
      • 本质原因
      • 总结

现有一些电线,有管径、材质、长度三个属性,一次遍历可以实现相同管径和材质总长分类统计吗

一、概述

可以实现,一次遍历完全能完成按相同管径和材质分类统计总长的需求。

核心逻辑是在遍历过程中,同时以“管径+材质”为组合条件进行分组,并实时累加每组的长度,无需多次遍历数据。

实现的关键逻辑

  1. 选择合适的数据结构
    需使用一个能存储“键-值”对的结构,其中键(Key)是“管径+材质”的组合(如元组形式),值(Value)是该组合对应的累计总长。常见的结构包括Python中的字典(dict)、Java中的HashMap等。

  2. 单次遍历中的操作步骤
    遍历每条线时,执行以下3步操作,全程仅扫描一次数据:

    • 提取当前线的“管径”和“材质”,组合成唯一键。
    • 检查该键是否已存在于数据结构中。
    • 若存在,将当前线的长度累加到对应的值上;若不存在,新增该键,并将当前线的长度设为初始值。

示例场景(以Python为例)

假设线材数据格式为列表,每个元素是包含“管径、材质、长度”的字典,代码逻辑如下:

# 模拟线材数据wires=[{"管径":5,"材质":"铜","长度":10},{"管径":5,"材质":"铜","长度":20},{"管径":8,"材质":"铝","长度":15},{"管径":5,"材质":"铝","长度":5}]# 用于统计的字典,键为(管径, 材质),值为总长total_length={}# 一次遍历完成统计forwireinwires:key=(wire["管径"],wire["材质"])# 组合键ifkeyintotal_length:total_length[key]+=wire["长度"]# 累加长度else:total_length[key]=wire["长度"]# 初始化新组# 输出结果:{(5, '铜'): 30, (8, '铝'): 15, (5, '铝'): 5}print(total_length)

二、组合统计

以下是C++实现代码,使用std::map存储“管径+材质”组合与总长度的映射关系,通过一次遍历完成统计:

#include<iostream>#include<vector>#include<map>#include<string>// 定义线材结构体,包含管径、材质、长度三个属性structWire{intdiameter;// 管径(假设为整数,如需小数可改为double)std::string material;// 材质doublelength;// 长度(支持小数)};intmain(){// 模拟待统计的线材数据std::vector<Wire>wires={{5,"铜",10.5},{5,"铜",20.3},{8,"铝",15.0},{5,"铝",5.7},{8,"铝",8.2},{5,"铜",12.1}};// 用于统计的映射表:键为(管径, 材质)组合,值为该组合的总长度std::map<std::pair<int,std::string>,double>totalLengthMap;// 一次遍历完成统计for(constauto&wire:wires){// 构建组合键(管径+材质)autokey=std::make_pair(wire.diameter,wire.material);// 累加长度(若键不存在,会自动初始化并赋值)totalLengthMap[key]+=wire.length;}// 输出统计结果std::cout<<"统计结果(管径, 材质):总长度"<<std::endl;for(constauto&entry:totalLengthMap){std::cout<<"("<<entry.first.first<<", "<<entry.first.second<<"):"<<entry.second<<std::endl;}return0;}

代码说明:

  1. 数据结构选择
    使用std::map作为存储容器,键类型为std::pair<int, std::string>(组合管径和材质),值类型为double(存储总长度)。map会自动根据键的顺序排序,若无需排序可改用std::unordered_map(需自定义哈希函数,稍复杂)。

  2. 核心逻辑
    遍历所有线材时,通过std::make_pair生成“管径+材质”的唯一键,直接对map中该键对应的值做累加操作(map会自动处理“键不存在时初始化”的逻辑),全程仅遍历一次数据。

  3. 灵活性
    若管径为小数(如8.5mm),可将Wire中的diameter改为double,同时修改map的键类型为std::pair<double, std::string>即可。

输出结果:

统计结果(管径, 材质):总长度 (5, 铜):42.9 (5, 铝):5.7 (8, 铝):23.2

(结果为示例数据中相同管径和材质的长度累加值)

三、单属性统计

以下是按材质分类统计总长度的C++代码,核心逻辑仍是一次遍历,通过std::map(或std::unordered_map)以“材质”为键存储总长度,实现高效统计:

#include<iostream>#include<vector>#include<map>#include<string>// 线材结构体(同之前定义,包含管径、材质、长度)structWire{intdiameter;// 管径(可按需改为double)std::string material;// 材质doublelength;// 长度};intmain(){// 模拟线材数据std::vector<Wire>wires={{5,"铜",10.5},{5,"铜",20.3},{8,"铝",15.0},{5,"铝",5.7},{8,"铝",8.2},{5,"铜",12.1}};// 统计映射表:键为材质,值为该材质的总长度std::map<std::string,double>materialTotalLength;// 一次遍历完成统计for(constauto&wire:wires){// 以材质为键,累加长度(键不存在时自动初始化为0)materialTotalLength[wire.material]+=wire.length;}// 输出统计结果std::cout<<"各材质总长度统计:"<<std::endl;for(constauto&entry:materialTotalLength){std::cout<<entry.first<<":"<<entry.second<<std::endl;}return0;}

代码说明:

  1. 数据结构选择
    使用std::map<std::string, double>,键为材质字符串(如"铜"、“铝”),值为该材质的累计总长度。若无需按材质排序,可改用std::unordered_map(效率更高,无需排序逻辑)。

  2. 核心逻辑
    遍历每条线材时,直接以wire.material作为键,对map中对应的值做累加。map会自动处理“键不存在”的情况(初始值为0,再累加当前长度),全程仅需一次遍历。

  3. 结果验证
    示例数据中:

    • 铜的总长度 = 10.5 + 20.3 + 12.1 = 42.9
    • 铝的总长度 = 15.0 + 5.7 + 8.2 = 28.9

输出结果:

各材质总长度统计: 铜:42.9 铝:28.9

如需调整数据类型(如管径为小数、长度为整数),只需修改Wire结构体中对应字段的类型即可,统计逻辑无需变动。

四、说明一

std::map<std::string,double>materialTotalLength;std::map会排序吗,构建出map的顺序和原始数据是不是有关系

在C++中,std::map会自动排序的,其内部元素的顺序与原始数据的插入顺序无关,仅由键(key)的大小关系决定。

具体说明:

  1. std::map的排序特性
    std::map是一种有序关联容器,它内部通过红黑树(一种平衡二叉搜索树)实现,会自动根据键的大小对元素进行排序。默认情况下,排序规则由std::less<Key>决定(即“小于”比较),对于std::string类型的键,就是按照字典序(lexicographical order)排序的。

    例如,对于字符串键"铝""铜",在字典序中(取决于字符编码,通常中文按Unicode码点比较),"铜"会排在"铝"前面(实际编码中'铜'的Unicode值小于'铝'),因此std::map会将"铜"对应的键值对放在"铝"之前,无论原始数据中哪个材质先出现。

  2. 与原始数据顺序的关系
    std::map的元素顺序不受插入顺序影响。无论你先插入"铝"还是先插入"铜",最终map中都会按照键的排序规则重新排列。

    举例:
    若原始数据中材质出现的顺序是铝 → 铜 → 铝 → 铁,插入std::map后,最终顺序会按字典序排列(例如铜 → 铝 → 铁,具体取决于字符串实际比较结果),与原始插入顺序无关。

  3. 如何避免排序?
    若需要保持与插入顺序相关的“无序”状态(或不需要排序以提高性能),可以使用std::unordered_map。它是无序关联容器,内部通过哈希表实现,元素顺序不固定(通常与插入顺序无关,但也不保证排序),且插入/查找效率更高(平均O(1))。

代码示例验证:

#include<iostream>#include<map>#include<string>intmain(){std::map<std::string,int>myMap;// 按 "铝" → "铜" → "铁" 的顺序插入myMap["铝"]=1;myMap["铜"]=2;myMap["铁"]=3;// 输出map中的元素顺序(按键的字典序)std::cout<<"std::map 中的顺序:"<<std::endl;for(constauto&pair:myMap){std::cout<<pair.first<<" ";// 输出:铜 铁 铝(取决于实际编码的字典序)}return0;}

输出结果中,元素顺序由"铝""铁""铜"的字典序决定,而非插入时的"铝" → "铜" → "铁"

总结:

  • std::map会自动排序,顺序由键的比较规则(默认字典序)决定。
  • 排序结果与原始数据的插入顺序无关
  • 若需无序/与插入顺序弱相关的容器,优先使用std::unordered_map

五、说明二

std::map<std::pair<int,std::string>,double>totalLengthMap;又是怎样排序的

std::map<std::pair<int, std::string>, double>的排序规则由其键类型std::pair<int, std::string>的比较逻辑决定,遵循字典序(lexicographical order)排序,具体规则如下:

核心排序逻辑:先比第一个元素,再比第二个元素

std::pair的比较运算符(operator<)是C++标准库预定义的,其排序规则为:

  1. 优先比较pair的第一个元素(此处为int类型的管径):
    若两个pair的第一个元素(管径)不相等,则直接根据第一个元素的大小决定顺序(小的在前)。
  2. 若第一个元素相等,再比较第二个元素(此处为std::string类型的材质):
    此时按第二个元素(字符串)的字典序(std::stringoperator<规则,通常是字符编码的顺序)决定顺序。

举例说明

假设有以下std::pair<int, std::string>类型的键:
(5, "铜")(5, "铝")(8, "铝")(3, "铁")

排序步骤:

  1. 先比较第一个元素(管径):
    • 3 < 5 < 8,因此(3, "铁")排在最前,(8, "铝")排在最后。
  2. 对于管径相同的(5, "铜")(5, "铝"),比较第二个元素(材质字符串):
    • 字符串比较按字符编码(如Unicode),假设"铜"的编码值小于"铝",则(5, "铜")排在(5, "铝")之前。

最终排序结果为:
(3, "铁")(5, "铜")(5, "铝")(8, "铝")

本质原因

std::map默认使用std::less<Key>作为比较器,而std::less<Key>会调用Key类型的operator<。对于std::pair<T1, T2>,标准库已实现operator<,逻辑就是上述的“先比第一个元素,再比第二个元素”的字典序。

总结

std::map<std::pair<int, std::string>, double>的排序与键的两个元素都相关:

  • 先按int类型的管径升序排列
  • 管径相同的,再按std::string类型的材质字典序排列

排序结果与元素的插入顺序无关,仅由键的两个元素的大小关系决定。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/21 12:20:55

Qwen3-1.7B模型下载与安装一站式指南

Qwen3-1.7B模型下载与安装一站式指南 1. 引言&#xff1a;为什么选择Qwen3-1.7B&#xff1f; 你是否还在为大模型部署成本高、显存要求大而烦恼&#xff1f; 有没有一款模型&#xff0c;既能跑在普通笔记本上&#xff0c;又能保持足够强的语言理解能力&#xff1f; 答案是&a…

作者头像 李华
网站建设 2026/8/21 0:55:38

结合知识图谱有用吗?增强型语义填空系统构想

结合知识图谱有用吗&#xff1f;增强型语义填空系统构想 1. BERT 智能语义填空服务 你有没有遇到过一句话差一个词却怎么都想不起来的情况&#xff1f;或者写文章时卡在一个表达上&#xff0c;总觉得缺了点“味道”&#xff1f;如果有个 AI 能读懂上下文&#xff0c;精准补全…

作者头像 李华
网站建设 2026/8/21 12:20:09

5大实战技巧:让Compose Multiplatform在iOS上跑得飞起

5大实战技巧&#xff1a;让Compose Multiplatform在iOS上跑得飞起 【免费下载链接】compose-multiplatform JetBrains/compose-multiplatform: 是 JetBrains 开发的一个跨平台的 UI 工具库&#xff0c;基于 Kotlin 编写&#xff0c;可以用于开发跨平台的 Android&#xff0c;iO…

作者头像 李华
网站建设 2026/8/21 12:20:09

Qwen3-1.7B免费开源,个人开发者福音来了

Qwen3-1.7B免费开源&#xff0c;个人开发者福音来了 1. 引言&#xff1a;轻量级大模型的春天来了 你是否也曾因为设备算力不足而放弃在本地运行AI模型&#xff1f;或者因为高昂的API费用对云端服务望而却步&#xff1f;现在&#xff0c;这些问题有了全新的答案——Qwen3-1.7B…

作者头像 李华
网站建设 2026/8/21 12:20:08

终极指南:如何用RunCat让Windows任务栏变身萌宠桌面助手

终极指南&#xff1a;如何用RunCat让Windows任务栏变身萌宠桌面助手 【免费下载链接】RunCat_for_windows A cute running cat animation on your windows taskbar. 项目地址: https://gitcode.com/GitHub_Trending/ru/RunCat_for_windows RunCat是一款独特的Windows桌面…

作者头像 李华
网站建设 2026/8/21 12:24:06

Paraformer-large支持批量任务?队列系统集成部署方案

Paraformer-large支持批量任务&#xff1f;队列系统集成部署方案 1. 为什么需要批量处理——从单次上传到生产级语音转写 你有没有遇到过这样的场景&#xff1a;刚收到市场部发来的20个会议录音&#xff0c;每个30分钟以上&#xff1b;或者客服团队每天要处理上百条客户语音反…

作者头像 李华