c++ - Create list of unique object pairs -
i have qvector of instances of object atom, each atom instance contains set of cartesian coordinates , unique index identifier, among other attributes. have defined dyad container, tuple of 2 atom instances. basically, if 2 atom instances satisfy distance constraint, want able construct qlist of dyads.
say had dyad of (atom1,atom2), how ensure qlist did not contain dyad of (atom2, atom1)?
i have tried use qlist .contains() function , have overloaded == operator, cannot work. can attach code have tried insofar trying use contains() function if help.
// function definition
qlist<atomdyad> getuniqueatompairs(qvector<atom> atomvector) {
qlist<atomdyad> atomdyadpairlist; (int iatom = 0; iatom < atomvector.size(); iatom++) { (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 ensure mydyad(atomvector[jatom], atomvector[iatom]) not exist? atomdyadpairlist.append(mydyad); } } } return atomdyadpairlist;
i not sure know how atom , atomdyad classes like, mimic them in simple example idea. assume, atom has 3 coordinates: x, y , z. let's code now:
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 x, y , 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; } // compare 2 atoms. bool operator==(const atom &other) const { return m_x == other.m_x && m_y == other.m_y && m_z == other.m_z; } }; now let's define atomedyad class consists of 2 atoms:
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; } }; finally, let's store unique atomdyads. unit test:
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 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); you can check whether item added set checking return value of std::set::insert() function.
Comments
Post a Comment