QT关联容器QMap,QHash的Key值自动排序问题 (**)
对QMap中的key进行自定义排序 (***)
如何取消QMap自动排序,让QMap按照插入的顺序排列? (***)
通过插入顺序循环QHash
QMap,QHash插入后的显示顺序以及记录插入顺序的数据结构 (***)
基本框架 - QT常见数据结构:QString、QList、QVector、QMap、QHash、QSet、QPair快览
------------------------------------------------------------
要点:
1. QList<QPair<QString,QString>> pairs;
2. 改变QMap的key的排序规则,则需要提供operator<()
3. 其他数据结构
4. 实现按照自定义的 插入顺序
问题:QMap,QMultiMap均为关联容器,按照 key的 unicode码排序,无法自定义。
好像 map也可以实现多键值?
QList 可自定义顺序;但修改、替换、检索之类的操作,不同场景,不同方便?
在处理键值对这类场景中,QList似乎麻烦,没有对应关系,维护困难,容易产生错误。
QT List链表用法
使用 QMultiMap类,用数字作为排序的键值。
使用数字 key的 一个值作为 真实的键值,另一个作为 真实的值,
需要以下辅助:
不重复的 key总数,以及第一和最后一个key (***)
uniqueKeys / firstKey ~lastKey
qDebug()<<" uniqueKeys :: "<<multiMap.uniqueKeys(); //uniqueKeys :: (1, 2, 3)
qDebug()<<" lastKey :: "<<multiMap.lastKey(); //此时为 数字 number. lastKey :: 3
qDebug()<<" firstKey :: "<<multiMap.firstKey(); // firstKey :: 1
参考:
如何获得 multimap的中的key的数目 (**)
https://blog.csdn.net/ken2232/article/details/132061050
QHash & QMap 的顺序问题 (***)
https://blog.csdn.net/ken2232/article/details/132051508
------------------------------------------------------------
参考:
C++中operator关键字(重载操作符)
https://blog.csdn.net/ken2232/article/details/132053793
======================================
QMap,QHash插入后的显示顺序以及记录插入顺序的数据结构 (***)
1、QMap 插入后再遍历是:按照 key的顺序来排序的(汉字除外,汉字的排序顺序很奇怪,不是正常的字母顺序);
2、QHash插入后再遍历是 没有顺序的;
3、如果想按照插入顺序记录,可使用这样的结构:
QList <QPair <QString,QString>> pairs;
可以用这样的方式取数据:
QString firstValue=pairs.at(0).first;
QString secondValue=pairs.at(0).second;
————————————————
版权声明:本文为CSDN博主「想飞的兔子呀」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u012613604/article/details/78719570
如何取消QMap自动排序,让QMap按照插入的顺序排列?
简单实现:
#ifndef SEQUENTIALMAP
#define SEQUENTIALMAP
#include <QMap>
#include <QList>
template <class Key, class T>
class SequentialMap : public QMap<Key,T>
{
public:
T &operator[](const Key &key){
if(_keys.contains(key) == false){
this->_keys.append(key);
}
return QMap::operator [](key);
}//-----------------------------------------------------
const T operator[](const Key &key) const{
return QMap::operator [](key);
}//===================
QList<Key> keys() const{
return _keys;
}
private:
QList<Key> _keys;
};
#endif // SEQUENTIALMAP发布于 2021-07-10 15:18
https://www.zhihu.com/question/440927722
[QT编程系列-22]:基本框架 - QT常见数据结构:QString、QList、QVector、QMap、QHash、QSet、QPair快览
3. QPair和QMap比较
QPair和QMap是Qt中的两个不同的容器类,用于不同的目的。
QPair是一个用于存储两个值的通用容器类。它适用于需要将两个不同类型的值组合在一起的情况,但不提供键值对的查找和排序等功能。通过QPair,你可以方便地访问和操作这两个值,但无法根据键进行查找或按键排序。
相比之下,QMap是一个关联容器类,用于存储键值对。它提供了基于键的查找和插入操作,并可以按键进行排序。QMap可以根据键快速检索对应的值,并提供了按键排序的功能,因此在需要根据键进行查找和排序的情况下,QMap更适合使用。
如果你需要存储键值对并且希望可以根据键进行查找和排序,那么应该选择使用QMap。如果只是简单地需要将两个不同类型的值组合在一起,而不涉及到查找和排序,那么QPair就足够了。
需要根据具体的需求来选择使用QPair还是QMap,它们各自在不同的场景下具有不同的优势和用途。
————————————————
版权声明:本文为CSDN博主「文火冰糖的硅基工坊」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/HiWangWenBing/article/details/131750604
QT关联容器QMap,QHash的Key值自动排序问题 (**)
QT关联容器根据key -> value映射, 元素根据 key值大小排序,与插入顺序无关。
1. QMap 自动排序
2. QHash 速度更快
https://www.cnblogs.com/nxzwcx/p/7471458.html
对QMap中的key进行自定义排序 (***)
QMap的默认排序是按照key的升序进行排序。
如果我们想改变QMap的key的排序规则,则需要提供operator<()
QMap’s key type must provide operator<(). QMap uses it to keep its items sorted, and assumes that two keys x and y are equal if neither x < y nor y < x is true.
Qt帮助文档给的例子:
#ifndef EMPLOYEE_H
#define EMPLOYEE_Hclass Employee
{
public:
Employee() {}
Employee(const QString &name, const QDate &dateOfBirth);
...private:
QString myName;
QDate myDateOfBirth;
};
inline bool operator<(const Employee &e1, const Employee &e2)
{
if (e1.name() != e2.name())
return e1.name() < e2.name();
return e1.dateOfBirth() < e2.dateOfBirth();
}#endif // EMPLOYEE_H
也可以把operator<写成类成员函数。
自己写的一个例子:
在Qt中新建一个控制台程序:
main.cpp中
#include <QCoreApplication>
#include <QMap>
#include <QDebug>class MyString
{
public:
explicit MyString(const QString &str_) : str(str_) {}QString str;
//重载操作符
bool operator < (const MyString& other) const
{
return str > other.str;
}
};int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);QMap<MyString,int> stringMap;
//初始化数据
//数据插入容器
stringMap.insert(MyString("aa"), 4);
stringMap.insert(MyString("bb"), 3);
stringMap.insert(MyString("cc"), 2);
stringMap.insert(MyString("dd"), 1);QMapIterator<MyString, int> iter(stringMap);
while (iter.hasNext()) {
iter.next();
qDebug() << iter.key().str << ": " << iter.value() << Qt::endl;
}return a.exec();
}
运行结果:
就变成了key是按照QString进行降序排列。
如果代码改成这样:
class MyString
{
public:
explicit MyString(const QString &str_) : str(str_) {}QString str;
//重载操作符
bool operator < (const MyString& other) const
{
return str < other.str; //这里就改成小于号,QMap里的排序就成了升序和QMap<QString, int>默认排序一样了
}
};
我再写一个按照int降序排序的例子:
#include <QCoreApplication>
#include <QMap>
#include <QDebug>class MyInt
{
public:
explicit MyInt(const int &value_) : value(value_) {}int value;
//重载操作符
bool operator < (const MyInt& other) const
{
return value > other.value;
}
};int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);QMap<MyInt, QString> intMap;
//初始化数据
//数据插入容器
intMap.insert(MyInt(1), QString("aa"));
intMap.insert(MyInt(2), QString("bb"));
intMap.insert(MyInt(3), QString("cc"));
intMap.insert(MyInt(4), QString("dd"));QMapIterator<MyInt, QString> iter(intMap);
while (iter.hasNext()) {
iter.next();
qDebug() << iter.key().value << ": " << iter.value();
}return a.exec();
}
运行结果:
以上只是为了让举例的代码简单明了,没有写成get和set的方式对类成员变量进行操作,在项目中建议写出get和set的方法对类成员变量进行操作。
————————————————
版权声明:本文为CSDN博主「hp_cpp」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hp_cpp/article/details/109275892
如何取消QMap自动排序,让QMap按照插入的顺序排列?
不可以的,这是由QMap底层结构决定的。
The QMap class is a template class that provides a red-black-tree-based dictionary.
上面是从Qt帮助手册摘录的QMap说明,可以看到 QMap是基于红黑树实现的。
那么,你插入的节点是要被排序的,就不可能保证插入顺序了;
办法1:
如果要保证顺序,只能使用数组、链表这类结构。
办法2:
还有一种比较复杂的方法,就是根据你具体的业务,设计一个符合结构。
比如,你的业务中插入、查询和修改较多,删除操作较少,可以把Value和Key分别放在两个容器里面,每次插入数据的时候,引入一个当前的序列号Number:
QHash<Key, Number> keyHash;
QMap<Number, Value> valueMap;
这样valueMap可以保证按照插入顺序浏览,查询的时候通过keyHash找到key->Number,然后,使用Number在valueMap中找到对应的值。
这样做的好处是,当列表比较大的时候,查询效率会比直接使用数组和链表更高;
坏处是耗费2倍的资源,并且插入和删除需要对两个容器操作和同步,维护效率更低。
办法3:。。。。
链接:https://www.zhihu.com/question/440927722/answer/1695069460
通过插入顺序循环QHash
QHash不记得您的插入顺序。
它专为快速随机访问而设计。您使用迭代器获得的顺序是任意的。
如果你只有在QHash插入元素(无元素删除),你可以并行使用一个数组/列表。这不是一个非常优雅的解决方案,但是您只需要QHash容器就无法达到您想要的效果。