Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 查找向量中恰好重复一次的值_C++_Containers_Unique - Fatal编程技术网

C++ 查找向量中恰好重复一次的值

C++ 查找向量中恰好重复一次的值,c++,containers,unique,C++,Containers,Unique,我有一个四面体网格作为点向量(std::array)和一个四面体向量(std::array)。我想检查特定顶点是否属于网格的边界 为此,每个四面体定义了4个面([0,1,2]、[0,1,3]、[1,2,3]和[0,2,3])。面[0,1,2]被认为与面[0,2,1]或任何其他置换相等。如果面在所有网格中只存在一次,则面是边界。内部面显示两次。如果顶点属于边界面,则它是边界 我的计划是创建所有面的向量(std::array),然后删除出现两次的条目。如果两个条目出现两次,我想删除它们,而不仅仅是重

我有一个四面体网格作为点向量(
std::array
)和一个四面体向量(
std::array
)。我想检查特定顶点是否属于网格的边界

为此,每个四面体定义了4个面([0,1,2]、[0,1,3]、[1,2,3]和[0,2,3])。面[0,1,2]被认为与面[0,2,1]或任何其他置换相等。如果面在所有网格中只存在一次,则面是边界。内部面显示两次。如果顶点属于边界面,则它是边界

我的计划是创建所有面的向量(
std::array
),然后删除出现两次的条目。如果两个条目出现两次,我想删除它们,而不仅仅是重复的条目。此外,相等比较器必须能够检测两个面是否相等,同时考虑到可能的排列


我不知道如何继续进行,或者如果存储一个包含所有面的向量,然后删除元素是最好的解决方案。任何想法都会很有帮助

归根结底,创建比较函数,将容器中的值的排列视为相等

这样做的概念是:

  • 将容器中的值复制到
    std::vector
  • 然后对
    std::vector
    s进行排序
  • 然后使用
    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;
};

在函数
main
的末尾,您还将看到如何消除双精度。而且,他们两个。我们对向量进行排序,然后使用
std::nextant_find
,查看是否有两个双精度,一个在另一个之下。如果是这样的话,我们会把它们都抹掉。我们重复这个过程,直到不再有双精度。

您能更改点向量中值的顺序吗?如果你能做到这一点,那么你就不需要处理排列了。事实上,我可以。这将避免使用自定义比较器cmpPermLess和cmpPermEqual要检测的是两个置换是否相等,对吗?我本来打算用is_置换。因为你对两个面(数组)重载运算符<,我必须注意不要比较其他有其他不同含义的数组,对吗?是的,你是对的。这种方法消除了排列。它将两个排列视为相等。是的,同样正确,你需要比较“苹果与苹果”实际上,没有这个代码就有问题了。它适用于我的情况,我最多只有2个元素,但对于3个或更多偶数元素,它将失败。你能为文档目的更新它吗?
#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;
};