我需要一个地图,其中的键将是唯一的,每个键将是一个集或自定义POD结构,其中包含3个数据项。这些值只是指向对象实例的指针。
从阅读Qt的QMap和QHash的文档看,似乎我在地图中使用QSet作为键,那么我应该使用QHash,因为QSet提供的是operator==(),而不是operator<()。这是否合理的假设?然而,文档也说QHash需要一个“名为qHash ()的全局qHash函数”,但我不清楚它是如何提供的,或者它是否是QSet的一个隐式部分?
或者,如果我使用一个简单的结构作为我的键,我遇到了处理qHash()的相同问题,尽管一个简单的operator==()结构应该有一个可以接受的operator==()重载,它只是比较所有的数据,对吗?
请给我一些关于这里最好的方法的建议。
发布于 2014-03-07 08:11:38
我建议您使用QHash,除非您需要对密钥进行排序(我认为您没有)。
operator==函数已经由QSet提供,假设由集合管理的类也定义了操作符(所有基本数据类型和QString等都有)。
如果两个集合包含相同的元素,则认为它们是相等的。 这个函数需要值类型来实现operator==()。
您仍然需要提供通常定义如下的qHash()函数:
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()函数应该尽可能地尝试为不同的键返回不同的哈希值。
示例:
我为一个存储字符串的集合编写了一个小的测试应用程序:
#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 );
}这将产生以下输出:
---------------------------------
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: 2https://stackoverflow.com/questions/22242082
复制相似问题