将多个元素插入到 2D 块中

Inserting multiple elements into a 2D block

本文关键字:2D 块中 插入 元素      更新时间:2023-10-16

我正在尝试计算向量向量内一系列元素的能量。一旦特定元素具有正确的能量,它就会被推入另一个向量向量中。下面是一个例子,因为它很难解释:

bool energy(const std::vector<double> &vals)
{
  float sum = 0.0;
  for(unsigned i=0; (i < vals.size()); i++)
  {
     sum += (vals[i]*vals[i]);
  }
  //cout << sum << endl;
  return (sum >= 5);
}
int main(int argc, char *argv[]) {
 std::vector<vector<double> > vals {
    {0, 0, 0, 0, 0}, // This has an energy of "0" -> does not count
    {1, 1, 1, 1, 1}, // This has an energy of "5" -> push_back to vector[0]
    {1, 1, 1, 1, 1}, // This has an energy of "5" -> push_back to vector[0]
    {1, 1, 1, 1, 1}, // This has an energy of "5" -> push_back to vector[0]
    {1, 2, 1, 1, 1}, //This has an energy of "5" -> push_back to vector[0]
    {0, 0, 0, 0, 0}, // This has an energy of "0" -> does not count && start a new 
                                // vector
    {1, 2, 3, 4, 5}, // This has an energy of "55" -> push_back to vector[1]
    {1, 2, 3, 4, 5}, // This has an energy of "55" -> push_back to vector[1]
    {1, 2, 3, 4, 5}, // This has an energy of "55" -> push_back to vector[1]
    {1, 2, 3, 4, 5} // This has an energy of "55" -> push_back to vector[1]
};
std::vector<vector<double> > clusters; 
std::vector<vector<double> > tmp;
//std::for_each(vals.begin(), vals.end(), energy);
int j = 0;
for(unsigned i=0; (i < vals.size()); i++)
{
    if(energy(vals[i]))
    {
        clusters.resize(j + 1);
        clusters[j] = vals[i];
    }else if(!energy(vals[i]) && energy(vals[i+1]))
    {
        j++;
    }
}
for(unsigned i=0; (i < clusters.size()); i++)
{
    for(unsigned j=0; (j < clusters[i].size()); j++)
    {
        cout << clusters[i][j] << ' ';
    }
    cout << endl;
}
 }

应该发生什么

名为clusters向量的向量的2个元素,每个元素都包含以下值:

clusters[0] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1 };

`clusters[1] = 1, 2, 3, 4, 5, 
      1, 2, 3, 4, 5,
      1, 2, 3, 4, 5, 
      1, 2, 3, 4, 5}`

发生了什么事情?

量的向量似乎覆盖了插入其中的块。因此,我只是得到它发现的最后一个元素,而不是上述内容:

`cluster[0] = {1 2 1 1 1}
cluster[1] = {1 2 3 4 5}`

我的想法和尝试是将每个"块"存储在包含足够能量的向量向量中,然后将所有这些值推入vector<double>然后将该向量插入簇块中。

有没有另一种方法,一个更简单的解决方案来解决这个问题?

更正的代码:

#include<vector>
#include<iostream>
using namespace std;
bool energy(const std::vector<double> &vals)
{
  float sum = 0.0;
  for(unsigned i=0; (i < vals.size()); i++)
  {
     sum += (vals[i]*vals[i]);
  }
  //cout << sum << endl;
  return (sum >= 5);
}
int main(int argc, char *argv[]) {
 std::vector<vector<double> > vals {
    {0, 0, 0, 0, 0}, // This has an energy of "0" -> does not count
    {1, 1, 1, 1, 1}, // This has an energy of "5" -> push_back to vector[0]
    {1, 1, 1, 1, 1}, // This has an energy of "5" -> push_back to vector[0]
    {1, 1, 1, 1, 1}, // This has an energy of "5" -> push_back to vector[0]
    {1, 2, 1, 1, 1}, //This has an energy of "5" -> push_back to vector[0]
    {0, 0, 0, 0, 0}, // This has an energy of "0" -> does not count && start a new
                                // vector
    {1, 2, 3, 4, 5}, // This has an energy of "55" -> push_back to vector[1]
    {1, 2, 3, 4, 5}, // This has an energy of "55" -> push_back to vector[1]
    {1, 2, 3, 4, 5}, // This has an energy of "55" -> push_back to vector[1]
    {1, 2, 3, 4, 5} // This has an energy of "55" -> push_back to vector[1]
};
std::vector<vector<double> > tmp(vals.size());
std::vector<vector<double> > clusters(vals.size());
int j = 0;
for(unsigned i=0; (i < vals.size()); i++)
{
    if(energy(vals[i]))
    {
        clusters[j].insert(clusters[j].end(), vals[i].begin(), vals[i].end());
    }else if(!energy(vals[i]) && energy(vals[i+1]))
    {
        j++;
    }
}
for(unsigned i=0; (i < clusters.size()); i++)
{
    for(unsigned j=0; (j < clusters[i].size()); j++)
    {
        cout << clusters[i][j] << ' ';
    }
    cout << endl;
}
 }

输出为:

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 
1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 

你的问题在这里:

for(unsigned i=0; (i < vals.size()); i++)
{
    if(energy(vals[i]))
    {
        clusters.resize(j + 1);
        clusters[j] = vals[i];
    }
    else if(!energy(vals[i]) && energy(vals[i+1]))
    {
        j++;
    }
}

首先,你的energy函数返回一个int,所以当返回值不为零时,它会计算要true的条件,当它为 0 时,它将false

其次,您实际上是在if分支中执行push_back,但您只是推送当前向量(您没有将其附加到现有向量)。

为了解决这个问题,我建议使用map<int, vector<int>>,这样你就可以快速引用每个集群(例如,能量为 5 的集群的键为 5,因此您可以创建一个新向量并插入这些值,或者附加到已经存在的向量)。 如果在向量向量中需要它,则始终可以在对它们进行排序后遍历映射并将它们交换到向量向量中。

你可以

简化很多代码,所以它会更容易阅读和理解,例如拿你的能量函数,你可以使用算法把它写在一行中:

return std::inner_product(vals.begin(), vals.end(), vals.begin(), 0.) >= 5;

我更改了一段代码使其正常工作

  int j = 0;
  for(unsigned i=0; (i < vals.size()); i++)
  {
      if(energy(vals[i])) {
          clusters[j].insert(clusters[j].end, vals[i].begin(), vals[i].end());
      }
      if(!energy(vals[i]) && energy(vals[i+1])) {
        clusters.push_back( tmp );
        ++j;
      }
  }

不要使用调整大小。您只需将一个空向量push_back到集群中即可。

对于每个操作来附加一个向量,只需使用按范围插入

void insert (iterator position, InputIterator first, InputIterator last);

参考: http://en.cppreference.com/w/cpp/container/vector/insert