QHash & QMap 的顺序问题 (***)

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_H

  class 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:。。。。

发布于 2021-01-24 15:18

  链接:https://www.zhihu.com/question/440927722/answer/1695069460

通过插入顺序循环QHash

QHash不记得您的插入顺序。

它专为快速随机访问而设计。您使用迭代器获得的顺序是任意的

如果你只有在QHash插入元素(无元素删除),你可以并行使用一个数组/列表。这不是一个非常优雅的解决方案,但是您只需要QHash容器就无法达到您想要的效果。

  http://cn.voidcc.com/question/p-nbuhitgv-kk.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值