我如何制作一个QList unique ?

时间:2022-06-26 22:50:05

I have a QList consist of QVector3D. A QVector3D represents a vertex or a point. This List holds also all vertices of a STL-File. The problem is that a vertex exist multiple times in the list. In need a list of the unique vertices of a STL-File. How can i implement it with Qt 5.0.2?

我有一个由QVector3D组成的QList。QVector3D表示一个顶点或点。这个列表还包含一个stl文件的所有顶点。问题是一个顶点在列表中存在多次。需要一个stl文件的唯一顶点的列表。如何使用Qt 5.0.2实现它?

2 个解决方案

#1


4  

QSet uses a hash-function for ensuring the uniqueness of the value (QMap uses operator <) There is no qHash implementation for QVector3D in Qt. You could implement your own one e.g. as in example:

QSet使用一个hash-function来确保值的唯一性(QMap使用操作符<)QVector3D在Qt中没有QVector3D实现,您可以实现您自己的方法,例如:

//place anywhere in Qt-code
#include <QSet>
#include <QVector3D>
#include <QList>

uint qHash(const QVector3D &v)
{
    return qHash( QString( "%1x%2x%3" ).arg(v.x()).arg(v.y()).arg(v.z()) ) ;
}

int foo()
{
    QList<QVector3D> uvector3D_1;
    QSet<QVector3D> uvector3D_2;

    uvector3D_2 = QSet<QVector3D>::fromList(uvector3D_1);
return 0;
}

static int testFoo = foo();

Of cause it is not the fastest one, it relies on Qt's function qHash for QString. But I think it's good for demonstration.

因为它不是最快的,它依赖Qt函数qHash为QString。但我认为这是很好的示范。

#2


1  

QList<QVector3D> originalVector = ...;

then either:

然后:

QSet<QVector3D> noDublicatesSet = QSet<QVector3D>::fromList(originalVector);

or

QSet<QVector3D> noDublicatesSet = originalVector.toSet();

also you can add something like if you need QList back..

另外,如果你需要QList,你可以添加一些类似的东西。

QList<QVector3D> destinationVector = QList<QVector3D>::fromSet(noDublicatesSet);

you also will need those things (sorry has them in my code for ages.. forgot that they are external).. you might want to change hash function:

你也需要这些东西(对不起,我的代码已经有很多年了。)忘记他们是外在的)..你可能想要改变哈希函数:

#define ROTL10(x) (((x) << 10) | (((x) >> 22) & 0x000000ff))
#define ROTL20(x) (((x) << 20) | (((x) >> 12) & 0x0000ffff))

uint qHash(double data)
{
union U {
    quint64 n;
    double f;
};
U u;
u.f = data;
return u.f;
}

inline uint qHash(const QVector3D &v, uint seed)
{
return qHash(v.x()) ^ ROTL10(qHash(v.y())) ^ ROTL20(qHash(v.z()));
}

P.S. that's a code for Qt 5.0, actually to add missing qHash() for vectors, that's why they dont fit in QSet/QHash by default

这是Qt 5.0的代码,实际上是为向量添加缺失的qHash(),这就是为什么它们在默认情况下不适合QSet/ qHash。

#1


4  

QSet uses a hash-function for ensuring the uniqueness of the value (QMap uses operator <) There is no qHash implementation for QVector3D in Qt. You could implement your own one e.g. as in example:

QSet使用一个hash-function来确保值的唯一性(QMap使用操作符<)QVector3D在Qt中没有QVector3D实现,您可以实现您自己的方法,例如:

//place anywhere in Qt-code
#include <QSet>
#include <QVector3D>
#include <QList>

uint qHash(const QVector3D &v)
{
    return qHash( QString( "%1x%2x%3" ).arg(v.x()).arg(v.y()).arg(v.z()) ) ;
}

int foo()
{
    QList<QVector3D> uvector3D_1;
    QSet<QVector3D> uvector3D_2;

    uvector3D_2 = QSet<QVector3D>::fromList(uvector3D_1);
return 0;
}

static int testFoo = foo();

Of cause it is not the fastest one, it relies on Qt's function qHash for QString. But I think it's good for demonstration.

因为它不是最快的,它依赖Qt函数qHash为QString。但我认为这是很好的示范。

#2


1  

QList<QVector3D> originalVector = ...;

then either:

然后:

QSet<QVector3D> noDublicatesSet = QSet<QVector3D>::fromList(originalVector);

or

QSet<QVector3D> noDublicatesSet = originalVector.toSet();

also you can add something like if you need QList back..

另外,如果你需要QList,你可以添加一些类似的东西。

QList<QVector3D> destinationVector = QList<QVector3D>::fromSet(noDublicatesSet);

you also will need those things (sorry has them in my code for ages.. forgot that they are external).. you might want to change hash function:

你也需要这些东西(对不起,我的代码已经有很多年了。)忘记他们是外在的)..你可能想要改变哈希函数:

#define ROTL10(x) (((x) << 10) | (((x) >> 22) & 0x000000ff))
#define ROTL20(x) (((x) << 20) | (((x) >> 12) & 0x0000ffff))

uint qHash(double data)
{
union U {
    quint64 n;
    double f;
};
U u;
u.f = data;
return u.f;
}

inline uint qHash(const QVector3D &v, uint seed)
{
return qHash(v.x()) ^ ROTL10(qHash(v.y())) ^ ROTL20(qHash(v.z()));
}

P.S. that's a code for Qt 5.0, actually to add missing qHash() for vectors, that's why they dont fit in QSet/QHash by default

这是Qt 5.0的代码,实际上是为向量添加缺失的qHash(),这就是为什么它们在默认情况下不适合QSet/ qHash。