首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Qt映射容器中使用QSet作为密钥

在Qt映射容器中使用QSet作为密钥
EN

Stack Overflow用户
提问于 2014-03-07 05:16:07
回答 1查看 1.7K关注 0票数 2

我需要一个地图,其中的键将是唯一的,每个键将是一个集或自定义POD结构,其中包含3个数据项。这些值只是指向对象实例的指针。

从阅读Qt的QMap和QHash的文档看,似乎我在地图中使用QSet作为键,那么我应该使用QHash,因为QSet提供的是operator==(),而不是operator<()。这是否合理的假设?然而,文档也说QHash需要一个“名为qHash ()的全局qHash函数”,但我不清楚它是如何提供的,或者它是否是QSet的一个隐式部分?

或者,如果我使用一个简单的结构作为我的键,我遇到了处理qHash()的相同问题,尽管一个简单的operator==()结构应该有一个可以接受的operator==()重载,它只是比较所有的数据,对吗?

请给我一些关于这里最好的方法的建议。

EN

Stack Overflow用户

回答已采纳

发布于 2014-03-07 08:11:38

我建议您使用QHash,除非您需要对密钥进行排序(我认为您没有)。

operator==函数已经由QSet提供,假设由集合管理的类也定义了操作符(所有基本数据类型和QString等都有)。

如果两个集合包含相同的元素,则认为它们是相等的。 这个函数需要值类型来实现operator==()。

您仍然需要提供通常定义如下的qHash()函数:

代码语言:javascript
复制
inline uint qHash( QSet<whatever> set )
{
    return /* calculate a hash based on all the elements. */
}

只要定义QHash的代码包含包含定义的文件,这个定义就可以放在任何地方。如果在本例中有一个被引用为whatever的类,那么您将把这个定义放在类定义之后。

注意,qHash函数只需要确保方程obj1 == obj2的结果总是与qHash(obj1) == qHash(obj2)的结果相等。

这意味着您不必产生唯一的散列,但文档中有以下注意事项:

但是,为了获得良好的性能,qHash()函数应该尽可能地尝试为不同的键返回不同的哈希值。

示例:

我为一个存储字符串的集合编写了一个小的测试应用程序:

代码语言:javascript
复制
#include <QtCore/QSet>
#include <QtCore/QHash>
#include <QtCore/QList>
#include <QtCore/QDebug>    

typedef QSet<QString> QStringSet;
typedef QHash< QStringSet, QObject* > QStringSetToObjectHash;

inline uint qHash( const QStringSet mySet )
{
    // convert the set to a list so we can sort and iterate over it
    QList<QString> mySetAsList = mySet.toList();
    qSort( mySetAsList );

    // take the hash of the first item
    uint result = qHash( mySetAsList.first() );

    // for each remaining element in the list
    for( int index = 1; index < mySetAsList.count(); index++ )
    {
        // XOR the current result with the hash of the next item
        result ^= qHash( mySetAsList.at( index ) );
    }

    return result;
}
   
void insertIntoHash( QStringSetToObjectHash& hash, const QStringSet& key, QObject* const value )
{
    qDebug() << "---------------------------------";
    qDebug() << "Element hash value:" << qHash( key );

    foreach( QStringSet existingKey, hash.keys() )
    {
        if( existingKey == key )
        {
            qDebug() << "Similar element found using == operator. QHash will not store that item twice";
        }
    }

    hash.insert( key, value );
    qDebug() << "QHash count:" << hash.count();
}

int main(int argc, char *argv[])
{
    QStringSetToObjectHash testHash;

    QObject dummy;

    QStringSet testSet;
    testSet.insert( "1" );
    testSet.insert( "12" );

    insertIntoHash( testHash, testSet, &dummy );

    QStringSet testSet2( testSet );

    insertIntoHash( testHash, testSet2, &dummy );

    QStringSet testSet3;
    testSet3.insert( "12" );
    testSet3.insert( "1" );

    insertIntoHash( testHash, testSet3, &dummy );

    QStringSet testSet4;
    testSet4.insert( "1" );
    testSet4.insert( "2" );
    testSet4.insert( "3" );

    insertIntoHash( testHash, testSet4, &dummy );
}

这将产生以下输出:

代码语言:javascript
复制
--------------------------------- 
Element hash value: 883
QHash count: 1 
---------------------------------
Element hash value: 883  Similar element found using == operator. QHash will not store that item twice
QHash count: 1 
---------------------------------
Element hash value: 883  Similar element found using == operator. QHash will not store that item twice
QHash count: 1 
--------------------------------- 
Element hash value: 48
QHash count: 2
票数 2
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22242082

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档