Home > Net >  For Loop Misbehavior in C and Qt 6.2
For Loop Misbehavior in C and Qt 6.2

Time:12-25

First of all i'm a complete beginner in C and Qt and i'm using Qt 6.2 and C 11. This is the code that i have problem with:

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();

I was expecting that i would get the output of "10" but instead i got "1". I changed the code to this and it fixed the problem but i just can't wrap my head around it:

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();

i want to know why C is behaving like this.

CodePudding user response:

QSet is a collection of unique objects. The first code snipped produces 10 equal to each other myList objects. Thus, QSet gets only one unique myList object: qInfo() << listSet.count(); outputs 1.

The second snippet makes not equal myList objects, they differ by the first list items, and qInfo() << listSet.count(); outputs 10.

CodePudding user response:

Think about this:

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

So you are defining a set of a list of strings.

However all the lists you are creating in the inner loop are exactly the same.

Therefore the set will only keep one! This is actually the expected behavior.

When you added the change

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

then you made every item added unique since i is in the outer loop!

I did compile and run your first example modified as below

#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();
}

and it outputs

$ ./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

When you comment out that line you added, it becomes

$ ./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

CodePudding user response:

QSet is based on hash

Hi! Glad to answer your question! In a words, QSet is based on hash, if the hashes of the two items are equal, then the QSet will not open up a new space.And the hash calculation method of QList is based on its elements.

In other words, if two QList has the same elements, they will have the same hash. And because they have the same hash, the QSet will not open up a new space.

From your first code: every qlist has the same elements with:

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

because they have the same elements, so they will have the same hash. In the end, the QSet will only have one element.

But in your second code, every qlist have differrent hash:

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

As you can see, every qlist's first element is different, therefore they will have different hash, and QSet will open up a new space for every qlist.

I hope my understanding can help you!

  • Related