快速调整矢量的矢量大小以正确的大小(c++)

quick way of resizing vector of vectors to correct size (c++)

本文关键字:c++ 调整      更新时间:2023-10-16

我想调整std::vector>转换为已知大小(m, n),理想情况下不需要任何内存复制(T是float或double)。

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();
}

data是动态填充的,每次推回一行新数据。每个"行"都保证具有相同数量的元素。所以它实际上是一个m × n的表

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

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

目前我正在做data_norm = data在我的normalize()方法的开始只是为了确保data_norm被分配到正确的大小,没有进一步的重新分配。但这需要复制所有的内存。有没有办法在没有内存副本的情况下做到这一点?

我看到这篇文章建议

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)被初始化和分配,而且我已经有了一个合适大小的源向量。

我希望有一种方法可以用类似调整大小的方法来做到这一点?但是如果没有遍历和调整每个子向量的大小——我猜这会造成疯狂的重新分配。

您可以使用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

目前我正在做data_norm = data在我的normalize()方法的开始只是为了确保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}) {}
}

如果你想为任意维度做同样的事情,也可以这样做