快速调整矢量矢量以校正大小的方法(c ++)

时间:2015-10-23 02:00:35

标签: c++ optimization vector

我想调整std :: vector<的大小。的std ::矢量< T> >尽可能有效地知道已知大小(m,n),理想情况下没有任何存储器复制(T是浮点数或双精度数)。

class Foo {
    std::vector< std::vector< T > > data;
    std::vector< std::vector< T > > data_norm;

    std::vector< T > min_values;
    std::vector< T > max_values;

    void normalize();
}
动态填充

数据,一次push_back新数据一行'行'。每个“行”保证具有相同数量的元素。所以它实际上是一个m x n表。

然后在某一点上我调用 normalize ()方法:

  • 扫描数据
  • 找到每个列的最小/最大值,并将它们写入 min_values max_values
  • 将每个元素规范化为该列的最小值/最大值并存储在 data_norm

目前我正在 normalize ()方法的开头做 data_norm = data ,只是为了确保将 data_norm 分配给正确的大小,没有进一步的重新分配。但这涉及复制所有内存。没有这个记忆副本,有没有办法做到这一点?

我看过this帖子暗示

std::vector<std::vector<T>> my_vec(m, std::vector<T>(n))

但是在我的情况下, my_vec 已经存在。我可以创建并分配 new_vec

std::vector<std::vector<T>> new_vec(m, std::vector<T>(n));
data_norm = new_vec;

但我猜这仍然会有内存副本,实际上它会比 data_norm = data 慢,因为初始化了一个全新的向量( new_vec )和已分配,我已经有一个正确大小的源向量。

我希望有一种方法可以使用类似调整大小的方法吗?但是没有迭代并在每个子向量上调整大小 - 这会产生疯狂的重新分配,我猜。

2 个答案:

答案 0 :(得分:2)

您可以使用vector::resize(),而无需创建临时矢量

http://www.cplusplus.com/reference/vector/vector/resize/

// resizing vector
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector;

  // set some initial content:
  for (int i=1;i<10;i++) myvector.push_back(i);

  myvector.resize(5);
  myvector.resize(8,100);
  myvector.resize(12);

  std::cout << "myvector contains:";
  for (int i=0;i<myvector.size();i++)
    std::cout << ' ' << myvector[i];
  std::cout << '\n';

  return 0;
}

输出:

myvector contains: 1 2 3 4 5 100 100 100 0 0 0 0

答案 1 :(得分:1)

  

目前我在normalize()方法的开头做data_norm = data,只是为了确保data_norm被分配到正确的大小,并且没有进一步的重新分配。

首先,你应该简单地设计你的程序,这样任何人都无法调整向量的大小并确保你没有调整它们的大小,然后你可以完全避免这项工作。您可以在代码中放置一些断言,以确保在调试模式下大小永远不会改变,如果您想要更安全的话。

另外,如果你想“尽可能高效地”完成工作,那么你应该避免使用矢量向量,因为矩形矩阵的分配比必要的多。

目前还没有标准容器提供带有运行时边界的高效多维数组,但您可以很容易地定义一个。这是一个非常小的例子。

template<typename T>
class vector2d {
  std::vector<T> data;
  int columns;

public:
  struct index { int r, c; };

  vector2d(index i) : data(i.r * i.c), columns(i.c) {}
  T &operator[] (index i) { return data[i.r*columns + i.c]; }
}

然后你可以写:

class Foo {
    vector2d<T> data;
    vector2d<T> data_norm;

    std::vector<T> min_values;
    std::vector<T> max_values;

    void normalize();

    Foo(int n, int m) : data({n, m}), data_norm({n, m}) {}
}

如果你想为任意数量的维that can be done做同样的事情。