创建一个唯一对象对列表

3
我有一个QVector的对象实例,名为Atom。每个Atom实例都包含一组笛卡尔坐标和唯一的索引标识符,以及其他属性。我还定义了一个Dyad容器,它只是两个Atom实例的元组。基本上,如果我的两个Atom实例满足距离约束,我想能够构建一个Dyad的QList。
假设我有一个Dyad(Atom1,Atom2),如何确保我的QList没有包含(Atom2,Atom1)的Dyad?
我已经尝试使用QList.contains()函数并重载了我的==运算符,但我无法使其工作。如果需要,我可以附上到目前为止尝试使用contains()函数的代码。
// 函数定义
QList getUniqueAtomPairs(QVector atomVector) {
QList<AtomDyad> AtomDyadPairList;

for (int iatom = 0; iatom < atomVector.size(); iatom++) {
    for (int jatom = 0; jatom < atomVector.size(); jatom++) {

        if (iatom == jatom) { continue; }

        float x1 = atomVector[jatom].getX();
        float x2 = atomVector[iatom].getX();

        float y1 = atomVector[jatom].getY();
        float y2 = atomVector[iatom].getY();

        float z1 = atomVector[jatom].getZ();
        float z2 = atomVector[iatom].getZ();

        float Radii_Sum1 = atomVector[jatom].getvdW_radius(atomVector[jatom]) + atomVector[iatom].getvdW_radius(atomVector[iatom]);

        if (DistanceBetween3DPoints(x1, x2, y1, y2, z1, z2) <= Radii_Sum1) {
            AtomDyad MyDyad(atomVector[iatom], atomVector[jatom]);
            // How can I ensure that MyDyad(atomVector[jatom], atomVector[iatom]) does not already exist?
            AtomDyadPairList.append(MyDyad);
        }
    }
}

return AtomDyadPairList;
1个回答

1

我不确定我是否完全了解您的AtomAtomDyad类是什么样子的,但我将在一个简单的示例中模拟它们,以帮助您理解。 我假设Atom有三个坐标:x、y和z。 现在让我们编写代码:

struct Atom
{
  Atom(float x, float y, float z)
    : m_x(x), m_y(y), m_z(z)
  {}
  float m_x;
  float m_y;
  float m_z;

  // Sort first by x, than by y and finally by z coordinates.
  bool operator<(const Atom &other) const
  {
    if (m_x < other.m_x)
    {
      return true;
    }
    else if (m_x == other.m_x)
    {
      if (m_y < other.m_y)
      {
        return true;
      }
      else if (m_y == other.m_y)
      {
        if (m_z < other.m_z)
        {
          return true;
        }
      }
    }
    return false;
  }

  // To compare two atoms.
  bool operator==(const Atom &other) const
  {
    return m_x == other.m_x && m_y == other.m_y && m_z == other.m_z;
  }
};

现在让我们定义一个由两个原子组成的 AtomeDyad 类:
struct AtomDyad
{
  AtomDyad(const Atom &a1, const Atom &a2)
    : m_a1(a1), m_a2(a2)
  {}
  Atom m_a1;
  Atom m_a2;

  bool operator<(const AtomDyad &other) const
  {
    if (m_a1 == other.m_a2 && m_a2 == other.m_a1)
    {
      return false;
    }

    if (m_a1 < other.m_a1)
    {
      return true;
    }
    else if (m_a1 == other.m_a1)
    {
      if (m_a2 < other.m_a2)
      {
        return true;
      }
    }
    return false;
  }  
};

最后,让我们存储唯一的AtomDyads。一个单元测试:
std::set<AtomDyad> uniqueAtomDyad;

Atom a1(0, 0, 0);
Atom a2(0, 0, 1);
Atom a3(0, 1, 1);
Atom a4(1, 1, 1);

AtomDyad ad1(a1, a2);
AtomDyad ad2(a3, a4);
AtomDyad ad3(a1, a2); // same as ad1
AtomDyad ad4(a4, a3); // swapped ad3
AtomDyad ad5(a1, a1);
AtomDyad ad6(a1, a1);

uniqueAtomDyad.insert(ad1);
uniqueAtomDyad.insert(ad2);
uniqueAtomDyad.insert(ad3); // not unique
uniqueAtomDyad.insert(ad4); // not unique
uniqueAtomDyad.insert(ad5);
uniqueAtomDyad.insert(ad6); // not unique

assert(uniqueAtomDyad.size() == 3);

你可以通过检查 std::set::insert() 函数的返回值来判断一个元素是否被添加到了集合中。

使用您的示例,我能够引导我的代码以实现我所需的功能,谢谢。 - Ecaloota

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接