【Qt】Qt中关联容器QMap,QMultiMap,QHash,QMultiHash 的理解

news2025/1/15 6:59:38

在Qt中,有几种关联容器可供选择:

  1. QMap:QMap是一个关联容器,存储键-值对,并根据键自动进行排序。它提供了快速的查找和插入操作,适用于需要根据键进行排序和搜索的场景。

  2. QMultiMap:QMultiMap是一个关联容器,类似于QMap,但允许有重复的键。它还保了插入元素的顺序,可通过迭代器进行遍历。

  3. QHash:QHash是一个关联容器,根据键的哈希值进行快速查找和插入操作。它不会对键进行排序,适用于需要快速查找的场景。

  4. QMultiHash:QMultiHash是一个关联容器,类似于QHash,但允许有重复的键。它还保留了插入元素的顺序,可以通过迭代器进行遍历。

这些关联容器在Qt中提供了灵活而强大的数据结构选项,根据具体的需求和使用场景,您可以选择适合的容器来存储和管理数据。需要注意的是,这些容器都是基于Qt的容器类提供的,并且为了方便使用,它们也提供了类似STL容器的接口和使用方式。

1.QMap:QMap 是一个有序的关联容器,它根据键的排序来存储键-值对。示例用法如下:

#include <QMap>
#include <QDebug>

int main() {
    QMap<int, QString> map;
    
    // 插入键值对
    map.insert(1, "Apple");
    map.insert(2, "Banana");
    map.insert(3, "Orange");
    
    // 通过键查找值
    qDebug() << map.value(2);
    
    // 遍历所有键值对
    for(auto it = map.begin(); it != map.end(); ++it) {
        qDebug() << "Key:" << it.key() << "Value:" << it.value();
    }
    
    return 0;
}

2.QHash:QHash 是一个无序的关联容器,通过哈希函数来查找键-值对。示例用法如下:

#include <QHash>
#include <QDebug>

int main() {
QHash<QString, int> hash;

// 插入键值对
hash.insert("Apple", 10);
hash.insert("Banana", 20);
hash.insert("Orange", 30);

// 通过键查找值
qDebug() << hash.value("Banana");

// 遍历所有键值对
QHash<QString, int>::iterator it;
for(it = hash.begin(); it != hash.end(); ++it) {
    qDebug() << "Key:" << it.key() << "Value:" << it.value();
}

return 0;
}

3.QMultiMap:QMultiMap 是一个允许有重复键的有序关联容器。示例用法如下:

#include <QMultiMap>
#include <QString>
#include <QDebug>

int main()
{
    QMultiMap<int, QString> multimap;

    // 插入键值对
    multimap.insert(1, "apple");
    multimap.insert(2, "banana");
    multimap.insert(1, "orange");
    multimap.insert(3, "grape");

    // 使用迭代器遍历multimap
    qDebug() << "Multimap elements:";
    for (auto it = multimap.begin(); it != multimap.end(); ++it) {
        qDebug() << it.key() << "->" << it.value();
    }

    // 使用equal_range函数查找与键关联的元素范围
    auto range = multimap.equal_range(1);
    qDebug() << "Elements with key 1:";
    for (auto it = range.first; it != range.second; ++it) {
        qDebug() << it.key() << "->" << it.value();
    }

    return 0;
}

输出为:

Multimap elements:
1 -> "apple1 -> "orange"
2 -> "banana"
3 -> "grape"
Elements with key 1:
1 -> "apple"
1 -> "orange"

在上述示例中,我们使用QMultiMap类创建了一个multimap对象,并通过insert函数插入了一些键值对。然后,我们使用迭代器循环遍历整个multimap,并使用equal_range函数查找与键关联的元素范围。

(出错)注释:使用foreach时候,注意打印的时候,打印hash.values(key),要使用values
否则就会出错,如果使用的是value,那么会打印两次相同的值,出现了类似覆盖,实际上是取出的key,hash会映射出它认为要映射出的值。
在这里插入图片描述
这里还需要注意一个地方:它内部的存储结构到底是怎样的?下面的图解释的清晰:
在这里插入图片描述
可以看出multihash中存储key的地址都是不一样的。说明一个新的映射,就会有新的地址。

4.以下是一个使用QMultiHash的示例用法:

#include <QMultiHash>
#include <QDebug>

int main() {
    QMultiHash<int, QString> multiHash;
    
    // 向多重哈希表插入键-值对
    multiHash.insert(1, "Apple");
    multiHash.insert(2, "Banana");
    multiHash.insert(1, "Orange");
    multiHash.insert(3, "Grape");
    
    // 遍历所有键值对
    for(auto it = multiHash.begin(); it != multiHash.end(); ++it) {
        qDebug() << "Key:" << it.key() << "Value:" << it.value();
    }
    
    // 查找特定键的值
    int key = 1;
    QList<QString> values = multiHash.values(key);
    qDebug() << "Values for key" << key << ":" << values;
    
    return 0;
}

在上述示例中,我们创建了一个QMultiHash对象,并使用insert函数向哈希表中插入了多个键-值对。注意,由于QMultiHash允许存在重复的键,因此可以插入多个具有相同键的值。然后,我们使用迭代器遍历了整个多重哈希表,并打印出每个键值对。

接着,我们演示了如何使用values函数来查找特定键的所有值,并将它们存储在一个QList中。

那么有一个问题,QMultiHash和QMultiMap到底有哪些区别?

QMultiHashQMultiMap是Qt提供的两种关联容器,它们都允许键的重复,但在实现和使用上有一些区别:

  1. 数据结构:QMultiHash使用哈希表作为其底层数据结构,而QMultiMap使用有序的红黑树。由于哈希表的特性,QMultiHash在插入和查找操作上通常比QMultiMap更快,因为它使用哈希函数进行数据存储和问。而QMultiMap能够保持数据的有序性,适合需要保持插入顺序的场景。

  2. 迭代器顺序:QMultiHash迭代器的顺序是不确定的,而QMultiMap的迭代器是根据键的排序顺序进行遍历的,因为QMultiMap使用红黑树实现了基于排序的容器。

  3. 接口差异:尽管两者提供了类似的接口,包括插入、查找、删除等功能,但在一些特定操作上有所不同,比如QMultiHashvalues函数返回一个列表,但对于QMap,您可以使用find函数查找特定键的范围。

根据需求,您可以选择QMultiHashQMultiMap来适应不同的场景。如果需要快速的插入和查找操作,并且键的顺序并不重要,QMultiHash是更好的选择。而如果需要保持有序并且对键的顺序有要求,QMultiMap更适合。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1016627.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件测评中:电子政务系统怎么测评?

1、文件依据&#xff1a; 1)《中华人民共和国政府采购法实施条例》&#xff08;中华人民共和国国务院令 第658号&#xff09; 第四十一条“大型或者复杂的政府采购项目&#xff0c;应当邀请国家认可的质量检测机构参加验收工作。” 2) 《国务院办公厅关于印发国家政务信息化…

深入Android系统基础知识及基本概念

深入Android系统基础知识及基本概念 Android应用程序的基本组成部分&#xff0c;包括Activities&#xff08;活动&#xff09;、Services&#xff08;服务&#xff09;、Broadcast receivers&#xff08;广播接收器&#xff09;和Content providers&#xff08;内容提供者&…

Mysql---第八篇

系列文章目录 文章目录 系列文章目录一、mysql执行计划怎么看一、mysql执行计划怎么看 执行计划就是sql的执行查询的顺序,以及如何使用索引查询,返回的结果集的行数 EXPLAIN SELECT * from A where X=? and Y=? 1。id :是一个有顺序的编号,是查询的顺序号,有几个 sel…

ModbusTCP服务端

1在Device下&#xff0c;添加设备net&#xff1a; 公交车。 2在net下添加 ModbusTCP

技术人员如何提升商业敏感度?

在商业领域&#xff0c;最基本也是最实用的财务知识&#xff0c;就是看懂三张报表。简单地说&#xff0c;现金流量表&#xff0c;决定企业能不能活下来&#xff1b;资产负债表和利润表&#xff0c;决定企业活得好不好。下面分别来学习这三张报表。 资产负债表 资产负债表&#…

浅谈一下前端字符编码

背景 众所周知&#xff0c;计算机只能识别二进制&#xff0c;它是由逻辑电路组成&#xff0c;逻辑电路通常只有两个状态&#xff0c;开关的接通与断开&#xff0c;这两种状态正好可以用二进制数的0和1表示。但是现实中存在着其他的字符&#xff1a;数字、字母、中文、特殊符号…

如何实现Web应用、网站状态的监控?

如何实现Web应用、网站状态的监控&#xff1f; 关键词&#xff1a;网站监控,服务器监控,页面性能监控,用户体验监控本文通过代码分析、网站应用介绍网站状态监控的方式下文主要分为网站应用、技术实现两部分 一、网站应用 现在网络上已经存在一些Web网站监控的服务&#xff…

Vue ——08、路由嵌套,参数传递及重定向

路由嵌套&#xff0c;参数传递及重定向 一、路由嵌套二、参数传递第一种方式&#xff1a;第二种方式&#xff1a; 三、重定向————————创作不易&#xff0c;如觉不错&#xff0c;随手点赞&#xff0c;关注&#xff0c;收藏(*&#xffe3;︶&#xffe3;)&#xff0c;谢…

【C++杂货铺】继承由浅入深详细总结

文章目录 一、继承的概念及定义1.1 继承的概念1.2 继承定义1.2.1 定义格式1.2.2 继承方式和访问限定符1.2.3 继承基类成员访问方式的变化 二、基类和派生类对象赋值转换三、继承中的作用域四、派生类中的默认成员函数4.1 默认构造函数4.2 拷贝构造函数4.3 赋值运算符重载函数4.…

03使用Spring基于XML的方式注册第一个组件

基于XML的方式注册第一个组件 开发步骤 第一步: 创建Maven工程配置生成的pom.xml文件, 添加spring context基础依赖和junit依赖(注意根据Spring官方文档描述,Spring6需要JDK版本17) 当添加Spring的基础依赖spring context之后,Maven会自动关联并引入其他依赖spring aop, spr…

前端生态系统:构建现代Web应用的完整指南

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 前端开发生态系统是一个…

Selenium常见问题解析

1、元素定位失败&#xff1a; 在使用Selenium自动化测试时&#xff0c;最常见的问题之一是无法正确地定位元素&#xff0c;这可能导致后续操作失败。解决方法包括使用不同的定位方式&#xff08;如xpath、CSS selector、id等&#xff09;&#xff0c;等待页面加载完全后再进行…

[NLP] LLM---<训练中文LLama2(二)>扩充LLama2词表构建中文tokenization

使用SentencePiece的除了从0开始训练大模型的土豪和大公司外&#xff0c;大部分应该都是使用其为当前开源的大模型扩充词表&#xff0c;比如为LLama扩充通用中文词表&#xff08;通用中文词表&#xff0c;或者 垂直领域词表&#xff09;。 LLaMA 原生tokenizer词表中仅包含少量…

asp.net+sqlserver医院体检信息管理系统

一、源码描述 这是一款简洁十分美观的ASP.NETsqlserver源码&#xff0c;界面十分美观&#xff0c;功能也比较全面&#xff0c;比较适合 作为毕业设计、课程设计、使用&#xff0c;感兴趣的朋友可以下载看看哦 二、功能介绍 该源码功能十分的全面&#xff0c;具体介绍如下&…

PyTorch深度学习实战——基于ResNet模型实现猫狗分类

PyTorch深度学习实战——基于ResNet模型实现猫狗分类 0. 前言1. ResNet 架构2. 基于预训练 ResNet 模型实现猫狗分类相关链接 0. 前言 从 VGG11 到 VGG19&#xff0c;不同之处仅在于网络层数&#xff0c;一般来说&#xff0c;神经网络越深&#xff0c;它的准确率就越高。但并非…

Linux学习第12天:基于API函数的字符设备驱动开发:一字一符总见情

本节学习的内容主要为基于LinuxAPI函数的字符设备驱动的开发&#xff0c;还包括在驱动模块加载的时候如何自动创建设备节点。总结的脑图如下&#xff1a; 一、驱动原理 1.分配和释放设备号 申请设备号函数&#xff1a; int alloc_chrdev_region(dev_t *dev, unsigned basemin…

改进YOLOv5小目标检测:构建多尺度骨干和特征增强模块,提升小目标检测

构建多尺度骨干和特征增强模块,提升小目标检测 背景代码使用配置文件如下🔥🔥🔥 提升小目标检测,创新提升 🔥🔥🔥 测试在小目标数据集进行提点 👉👉👉: 新设计的创新想法,包含详细的代码和说明,具备有效的创新组合 🐤🐤🐤 1. 本文包含两个创新改…

SQL优化--count优化

select count(*) from tb_user ;在之前的测试中&#xff0c;我们发现&#xff0c;如果数据量很大&#xff0c;在执行count操作时&#xff0c;是非常耗时的。 MyISAM 引擎把一个表的总行数存在了磁盘上&#xff0c;因此执行 count(*) 的时候会直接返回这个 数&#xff0c;效率很…

档案管理系统设计与实现

摘 要 近年来&#xff0c;随着企业彼此间的竞争日趋激烈&#xff0c;信息技术在企业的发展中占据着越来越重要的地位。在企业的运输生产中&#xff0c;档案已成为企业运输经营中不可或缺的一部分&#xff0c;为管理者进行管理决策和进行各种经营活动提供了重要的依据&#xf…

前后端分离--Vue的入门基础版

目录 一.前后端分离 二.Vue的简介 三.Vue的入门案例 四.Vue的生命周期 一.前后端分离 前后端分离是一种软件架构模式&#xff0c;将应用程序的前端&#xff08;用户界面&#xff09;和后端&#xff08;数据处理和业务逻辑&#xff09;独立开发、独立部署。在前后端分离的架…