Qt / C ++哈希哈希

时间:2019-05-13 14:06:01

标签: c++ qt perl

我正在将Perl程序转换为Qt / C ++。大多数代码都可以直接转换为C ++或Qt函数。但是,我不确定如何迁移哈希的Perl哈希。

这是我用来组织一些数据的多级哈希的示例

$series{$uid}{$studynum}{$seriesnum}{'exportseriesid'} = $exportseriesid;
$series{$uid}{$studynum}{$seriesnum}{'seriesid'} = $seriesid;
$series{$uid}{$studynum}{$seriesnum}{'subjectid'} = $subjectid;
$series{$uid}{$studynum}{$seriesnum}{'studyid'} = $studyid;
$series{$uid}{$studynum}{$seriesnum}{'modality'} = $modality;

我已经使用QHash来创建单级哈希,例如

QHash<QString, QString> cfg;
int n = cfg["threads"].toInt();

在C ++中或使用QHash是否有类似的方法?

更新:

我最终使用了嵌套的QMap。迭代QMap时会自动按键对它进行排序,而QHash则不会。这是我最终使用的代码

/* create a multilevel hash s[uid][study][series]['attribute'] */
QMap<QString, QMap<int, QMap<int, QMap<QString, QString>>>> s;

/* iterate through the UIDs */
for(QMap<QString, QMap<int, QMap<int, QMap<QString, QString>>>>::iterator a = s.begin(); a != s.end(); ++a) {
    QString uid = a.key();

    /* iterate through the studynums */
    for(QMap<int, QMap<int, QMap<QString, QString>>>::iterator b = s[uid].begin(); b != s[uid].end(); ++b) {
        int studynum = b.key();

        /* iterate through the seriesnums */
        for(QMap<int, QMap<QString, QString>>::iterator c = s[uid][studynum].begin(); c != s[uid][studynum].end(); ++c) {
            int seriesnum = c.key();

            int exportseriesid = s[uid][studynum][seriesnum]["exportseriesid"].toInt();

            /* etc... */
        }
    }
}

3 个答案:

答案 0 :(得分:3)

您可以像这样使用QHash:

QHash<QString, QHash<QString, QString>> two_level_hash;
two_level_hash["first_level"]["second_level"] = "your data";

这适用于具有所需级别计数的哈希。

答案 1 :(得分:3)

与哈希/字典的直接等效项是unordered_map。然后,您可以嵌套它们,就像在您的Perl示例中一样。这会导致层次结构可能难以维护,就像在脚本语言中将层次结构推得过头时一样。基本思想

#include<iostream>
#include<string>
#include<unordered_map>

using std::string;
using std::cout;
using std::endl;

int main() 
{
    typedef std::unordered_map<string, int>    bottom;
    typedef std::unordered_map<string, bottom> nextlev;
    std::unordered_map<string, nextlev>        h3d;

    h3d["toplev"]["nextlev"]["seriesid"]  = 3;
    h3d["toplev"]["nextlev"]["subjectid"] = 11;

    for (auto k: h3d) {
        cout << k.first << " => " << endl;
        for (auto k2: k.second) {
            cout << "\t" << k2.first << " => " << endl;
            for (auto k3: k2.second)
                cout << "\t\t" << k3.first << " => " << k3.second << endl;
        }
    }   

    return 0;
}

在某些用例中,这可能(或可能不会)表现不佳。您可能希望struct对值进行分组。有关更加复杂和谨慎的结构,请参见this post

最后,我真的建议将多级哈希作为一个类来实现。当链接的数据变得笨拙时,在脚本语言中也是一个好主意:将其重写为类。

答案 2 :(得分:0)

我对perl不熟悉,但从外观上看,我怀疑您需要这样的东西:

struct PropertyPath {
    QString uid;
    QString studynum; // or other type of your preference 
    QString seriesnum;// or other type of your preference 
    QString name;
}

uint qHash(const PropertyPath& p, uint seed = 0)
{
    auto h = qHash(p.uid, seed);
    h = qHash(p.studynum, h);
    h = qHash(p.seriesnum, h);
    h = qHash(p.name, h);
    return h;
}

QHash<PropertyPath, QString> cfg;