-1

首先,我是 C++ 和 Qt 的完整初学者,我正在使用 Qt 6.2 和 C++11。这是我有问题的代码:

QSet<QList<QString>> listSet;
for(int i = 0; i < 10; i++)
{
    QList<QString> myList;
    for(int r = 0; r < 10; r++)
    {
        myList << "Item" + QString::number(r);
    }
    listSet.insert(myList);
}

qInfo() << listSet.count();

我原以为我会得到“10”的输出,但我得到了“1”。我将代码更改为此并解决了问题,但我无法理解它:

QSet<QList<QString>> listSet;
for(int i = 0; i < 10; i++)
{
    QList<QString> myList;
    myList << "default" + QString::number(i);
    for(int r = 0; r < 10; r++)
    {
        myList << "Item" + QString::number(r);
    }
    listSet.insert(myList);
}

qInfo() << listSet.count();

我想知道为什么 C++ 会这样。

4

3 回答 3

2

QSet是独特对象的集合。剪断的第一个代码会产生 10 个彼此相等的myList对象。因此,QSet只得到一个唯一的myList对象:qInfo() << listSet.count();输出 1。

第二个片段生成不相等myList的对象,它们因第一个列表项而异,并qInfo() << listSet.count();输出 10。

于 2021-12-25T03:15:47.470 回答
0

想一想:

using StringList = QList<QString>;
using SetOfStringLists = QSet< StringList >;

因此,您正在定义一组字符串列表。

但是,您在内部循环中创建的所有列表都完全相同。

因此,该套装将只保留一个!这实际上是预期的行为。

添加更改时

myList << "default" + QString::number(i);

然后你让每个添加的项目都是独一无二的,因为i它在外循环中!

我确实编译并运行了您修改如下的第一个示例

#include <QSet>
#include <QList>
#include <QDebug>

int main() 
{
QSet<QList<QString>> listSet;
for(int i = 0; i < 10; i++)
{
    QList<QString> myList;
    //myList << "default" + QString::number(i);
    for(int r = 0; r < 10; r++)
    {
        myList << "Item" + QString::number(r);
    }
    listSet.insert(myList);
    qInfo() << myList;
}
qInfo() << listSet.count();
}

它输出

$ ./testqt
("Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
("Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
("Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
("Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
("Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
("Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
("Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
("Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
("Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
("Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
1

当您注释掉您添加的那一行时,它变成

$ ./testqt
("default0", "Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
("default1", "Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
("default2", "Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
("default3", "Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
("default4", "Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
("default5", "Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
("default6", "Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
("default7", "Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
("default8", "Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
("default9", "Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9")
10
于 2021-12-25T03:15:26.540 回答
0

QSet 基于散列

QSet 基于hash;如果两个项目的哈希值相等,则 QSet不会开辟新空间。而QList的hash计算方法是基于它的元素。

换句话说,如果两个 QList 具有相同的元素,它们将具有相同的散列。而且,由于它们具有相同的哈希,QSet 不会开辟新空间。

从您的第一个代码:每个 qlist 具有相同的元素:

{"Item0","Item1","Item2","Item3",....}

因为它们具有相同的元素,所以它们将具有相同的哈希值。最后,QSet 将只有一个元素。

但是,在您的第二个代码中,每个 qlist 都有不同的哈希:

qlist0: {"default0", "Item0", "Item1", ...}
qlist1: {"default1", "Item0", "Item1", ...}
...
...

正如你所看到的,每个 qlist 的第一个元素是不同的,因此它们会有不同的 hash,并且 QSet 会为每个 qlist 开辟一个新的空间。

于 2021-12-25T03:39:03.363 回答