C++ 在C+;中平均重复属性的最佳方法+;矢量

C++ 在C+;中平均重复属性的最佳方法+;矢量,c++,algorithm,vector,C++,Algorithm,Vector,我有一个包含许多结构的std::vector: struct PLY { int x; int y; int greyscale; } 某些帘布层的位置x和y可能是重复的,但其灰度值不一定是重复的。找到这些(定位)副本并用一个灰度值表示所有副本的平均灰度值的PLYinstance替换它们的最佳方法是什么 例如:PLY a{1,1188}是PLY b{1,1255}的副本。相同的(x,y)位置可能有不同的灰度。所以你需要检查,是层a1{1,1,1}重复层a2{2,2,1}

我有一个包含许多结构的
std::vector

struct PLY {
    int x;
    int y;
    int greyscale;
}
某些帘布层的位置
x
y
可能是重复的,但其
灰度值不一定是重复的。找到这些(定位)副本并用一个灰度值表示所有副本的平均灰度值的
PLY
instance替换它们的最佳方法是什么


例如:
PLY a{1,1188}
PLY b{1,1255}
的副本。相同的(x,y)位置可能有不同的灰度。

所以你需要检查,是
层a1{1,1,1}重复<代码>层a2{2,2,1}

所以简单的方法是重写
操作符==
来检查
a1.x==a2.x
a1.y==a2.y
。在您可以编写自己的函数
removeDuplicates(std::vector&mPLY)之后将使用此向量的迭代器,比较并删除。但如果您想太频繁地从数组中间删除,最好使用
std::list

所以您需要检查,is
PLY a1{1,1,1}重复<代码>层a2{2,2,1}

所以简单的方法是重写
操作符==
来检查
a1.x==a2.x
a1.y==a2.y
。在您可以编写自己的函数
removeDuplicates(std::vector&mPLY)之后将使用此向量的迭代器,比较并删除。但如果您想太频繁地从数组中间删除,最好使用
std::list

您可以先应用字典排序。在排序过程中,您应该注意溢出的
greyscale
。用目前的方法你们会有一些舍入误差,但它会很小,因为我先求和,然后才求平均值

在第二部分中,您需要从阵列中删除重复项。我使用额外的索引数组来复制每个元素不超过一次。如果您对
x
y
greyscale
有一些禁止值,则可以使用它,因此无需额外的数组

struct PLY {
    int x;
    int y;
    int greyscale;
};

int main()
{
    struct comp
    {
        bool operator()(const PLY &a, const PLY &b) { return a.x != b.x ? a.x < b.x : a.y < b.y; }
    };
    vector<PLY> v{ {1,1,1}, {1,2,2}, {1,1,2}, {1,3,5}, {1,2,7} };
    sort(begin(v), end(v), comp());

    vector<bool> ind(v.size(), true);
    int s = 0;
    for (int i = 1; i < v.size(); ++i)
    {
        if (v[i].x == v[i - 1].x &&v[i].y == v[i - 1].y)
        {
            v[s].greyscale += v[i].greyscale;
            ind[i] = false;
        }
        else
        {
            int d = i - s;
            if (d != 1)
            {
                v[s].greyscale /= d;
            }
            s = i;
        }
    }

    s = 0;
    for (int i = 0; i < v.size(); ++i)
    {
        if (ind[i])
        {
            if (s != i)
            {
                v[s] = v[i];
            }
            ++s;
        }
    }
    v.resize(s);
}
struct-PLY{
int x;
int-y;
内灰度;
};
int main()
{
结构组件
{
bool操作符()(常数层&a,常数层&b){返回a.x!=b.x?a.x
您可以先应用词典排序。在排序过程中,您应该注意溢出的
greyscale
。用目前的方法你们会有一些舍入误差,但它会很小,因为我先求和,然后才求平均值

在第二部分中,您需要从阵列中删除重复项。我使用额外的索引数组来复制每个元素不超过一次。如果您对
x
y
greyscale
有一些禁止值,则可以使用它,因此无需额外的数组

struct PLY {
    int x;
    int y;
    int greyscale;
};

int main()
{
    struct comp
    {
        bool operator()(const PLY &a, const PLY &b) { return a.x != b.x ? a.x < b.x : a.y < b.y; }
    };
    vector<PLY> v{ {1,1,1}, {1,2,2}, {1,1,2}, {1,3,5}, {1,2,7} };
    sort(begin(v), end(v), comp());

    vector<bool> ind(v.size(), true);
    int s = 0;
    for (int i = 1; i < v.size(); ++i)
    {
        if (v[i].x == v[i - 1].x &&v[i].y == v[i - 1].y)
        {
            v[s].greyscale += v[i].greyscale;
            ind[i] = false;
        }
        else
        {
            int d = i - s;
            if (d != 1)
            {
                v[s].greyscale /= d;
            }
            s = i;
        }
    }

    s = 0;
    for (int i = 0; i < v.size(); ++i)
    {
        if (ind[i])
        {
            if (s != i)
            {
                v[s] = v[i];
            }
            ++s;
        }
    }
    v.resize(s);
}
struct-PLY{
int x;
int-y;
内灰度;
};
int main()
{
结构组件
{
bool操作符()(常数层&a,常数层&b){返回a.x!=b.x?a.x
根据您对
Ply
的描述,您需要以下运算符:

auto operator==(const Ply& a, const Ply& b)
{
  return a.x == b.x && a.y == b.y;
}
auto operator<(const Ply& a, const Ply& b)
{
  // whenever you can be lazy!
  return std::make_pair(a.x, a.y) < std::make_pair(b.x, b.y);
}
有了这个,我们可以得到我们的算法:

auto foo()
{
  std::vector<Ply> v = {{1, 5, 10}, {2, 4, 6}, {1, 5, 2}};

  std::sort(std::begin(v), std::end(v));

  for (auto i = std::begin(v); i != std::end(v); ++i) { 
    decltype(i) j;
    int average;

    std::tie(average, j) = compute_average_duplicates(i, std::end(v));

    // C++17 (coming soon in a compiler near you):
    // auto [average, j] = compute_average_duplicates(i, std::end(v));

    if (i + 1 == j)
      continue;

    i->greyscale = average;
    v.erase(i + 1, j);
    // std::vector::erase Invalidates iterators and references
    // at or after the point of the erase
    // which means i remains valid, and `++i` (from the for) is correct
  }
}
auto-foo()
{
向量v={1,5,10},{2,4,6},{1,5,2};
std::sort(std::begin(v),std::end(v));
对于(自动i=std::begin(v);i!=std::end(v);++i){
decltype(i)j;
整数平均;
std::tie(average,j)=计算平均值(i,std::end(v));
//C++17(不久将在您身边的编译器中推出):
//auto[average,j]=计算平均值(i,std::end(v));
如果(i+1==j)
继续;
i->灰度=平均值;
v、 擦除(i+1,j);
//删除使迭代器和引用无效
//在擦除点或之后
//这意味着i仍然有效,“++i”(来自for)是正确的
}
}

根据您对
Ply
的描述,您需要以下运算符:

auto operator==(const Ply& a, const Ply& b)
{
  return a.x == b.x && a.y == b.y;
}
auto operator<(const Ply& a, const Ply& b)
{
  // whenever you can be lazy!
  return std::make_pair(a.x, a.y) < std::make_pair(b.x, b.y);
}
有了这个,我们可以得到我们的算法:

auto foo()
{
  std::vector<Ply> v = {{1, 5, 10}, {2, 4, 6}, {1, 5, 2}};

  std::sort(std::begin(v), std::end(v));

  for (auto i = std::begin(v); i != std::end(v); ++i) { 
    decltype(i) j;
    int average;

    std::tie(average, j) = compute_average_duplicates(i, std::end(v));

    // C++17 (coming soon in a compiler near you):
    // auto [average, j] = compute_average_duplicates(i, std::end(v));

    if (i + 1 == j)
      continue;

    i->greyscale = average;
    v.erase(i + 1, j);
    // std::vector::erase Invalidates iterators and references
    // at or after the point of the erase
    // which means i remains valid, and `++i` (from the for) is correct
  }
}
auto-foo()
{
向量v={1,5,10},{2,4,6},{1,5,2};
std::sort(std::begin(v),std::end(v));
对于(自动i=std::begin(v);i!=std::end(v);++i){
decltype(i)j;
整数平均;
std::tie(average,j)=计算平均值(i,std::end(v));
//C++17(不久将在您身边的编译器中推出):
//auto[average,j]=计算平均值(i,std::end(v));
如果(i+1==j)
继续;
i->灰度=平均值;
v、 擦除(i+1,j);
//标准::ve