这一切都归结为创建比较函数,将容器中值的排列视为相等。
这样做的概念是:
- 将容器中的值复制到
std::vector
- 然后对
std::vectors进行排序
- 然后使用
std::vector 中现有的比较功能
作为示例,我创建了一个通用 lambda 来执行此任务。请看:
auto cmpPermLess = [](const auto& c1, const auto& c2) -> bool {
std::vector v1(c1.begin(), c1.end());
std::vector v2(c2.begin(), c2.end());
std::sort(v1.begin(), v1.end());
std::sort(v2.begin(), v2.end());
return v1 < v2;
};
类似的方法也可以用于其他比较。
当然,您也可以定义简单的其他运算符重载或比较函数。但是机制总是一样的。将参数复制到std::vectors,然后排序,再对比std::vectors。
现在我将展示一些驱动程序代码来测试所有这些:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <set>
#include <array>
#include <iterator>
// A generic Lambda for comparing containers and ignoring permutations
// Less than
auto cmpPermLess = [](const auto& c1, const auto& c2) -> bool { std::vector v1(c1.begin(), c1.end());
std::vector v2(c2.begin(), c2.end());
std::sort(v1.begin(), v1.end());
std::sort(v2.begin(), v2.end());
return v1 < v2;
};
// Equal
auto cmpPermEqual = [](const auto& c1, const auto& c2) -> bool { std::vector v1(c1.begin(), c1.end());
std::vector v2(c2.begin(), c2.end());
std::sort(v1.begin(), v1.end());
std::sort(v2.begin(), v2.end());
return v1 == v2;
};
// Example for Face definition
using Face = std::array<int, 3>;
// Example for a less than operator for Face
bool operator<(const Face& f1, const Face& f2) { return cmpPermLess(f1, f2); };
// Some test code for syntax check.
int main() {
// Define a vector with Faces
std::vector<Face> vf{ {0,1,2},{0,1,3},{1,2,0},{3,1,0},{1,2,3},{0,3,1},{1,3,0}};
std::cout << "\n\nOriginal Vector:\n";
for (const Face& f : vf) std::cout << f[0] << ' ' << f[1] << ' ' << f[2] << '\n';
// And some standalong faces
Face f1{ 2,1,0 }, f2{ 0,1,3 };
// Check less than operator
if (f1 < f2) {
std::cout << "\n\nF1 is less then F2\n";
}
// Check comparator for usage in algorithms
std::sort(vf.begin(), vf.end(), cmpPermLess);
std::cout << "\n\nSorted vector:\n";
for (const Face& f : vf) std::cout << f[0] << ' ' << f[1] << ' ' << f[2] << '\n';
// And check COmparator for usage in other containers
std::set<Face, decltype(cmpPermLess)> sf(vf.begin(),vf.end());
std::cout << "\n\nSet with unique elements:\n";
for (const Face& f : sf) std::cout << f[0] << ' ' << f[1] << ' ' << f[2] << '\n';
// Check comparator for usage in algorithms
std::sort(vf.begin(), vf.end(), cmpPermLess);
std::cout << "\n\nSorted vector:\n";
for (const Face& f : vf) std::cout << f[0] << ' ' << f[1] << ' ' << f[2] << '\n';
// Now the vector is sorted. Search doubles and delete them
for (std::vector<Face>::iterator it = std::adjacent_find(vf.begin(), vf.end(), cmpPermEqual);
it != vf.end();
it = std::adjacent_find(vf.begin(), vf.end(), cmpPermEqual)) {
vf.erase(it, it + 2);
}
std::cout << "\n\nDoubles eliminated:\n";
for (const Face& f : vf) std::cout << f[0] << ' ' << f[1] << ' ' << f[2] << '\n';
return 0;
};
最后,在函数main 中,您还将看到我们如何消除双打。而且,他们俩。我们对向量进行排序,然后使用std::adjacent_find,看看我们是否有两个双打,一个在另一个之下。如果是这样,我们将它们都删除。我们重复这个,直到不再有双打为止。