动态分配参差不齐的矩阵
Dynamically allocate ragged matrix
我正在尝试制作一个动态分配二维结构的通用函数。每行中的元素数不必对所有行都相同。结构表示为容器类型,其元素也是容器类型(例如一组列表)。该内部容器的元素类型也可以是任意的。容器仅支持 begin、end 和 size 函数。所有迭代器类型都必须支持迭代器操作。函数应该首先通过连续分配过程动态分配用于存储二维结构的space,然后将其接受的结构的元素重写到动态结构中。函数 returns 一个双指针,通过它可以访问此结构的元素。
#include <iostream>
#include <set>
#include <list>
#include <vector>
template < typename tip >
auto Make2DStructure(tip mat) {
using tip_objekta = typename std::decay < decltype(mat[0][0]) > ::type;
tip_objekta ** dynamic_mat = nullptr;
int rows = 0, total = 0;
for (auto i: mat) {
rows++;
for (auto j: i)
total++;
}
int columns[rows];
int k = 0;
for (auto i: mat) {
int num_of_colums = 0;
for (auto j: i)
num_of_colums++;
columns[k] = num_of_colums;
k++;
}
try {
dynamic_mat = new tip_objekta * [rows];
dynamic_mat[0] = new tip_objekta[total];
for (int i = 1; i < rows; i++)
dynamic_mat[i] = dynamic_mat[i - 1] + columns[i];
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns[i]; j++)
dynamic_mat[i][j] = mat[i][j];
} catch (...) {
delete[] dynamic_mat[0];
delete[] dynamic_mat;
throw std::bad_alloc();
}
return dynamic_mat;
}
int main() {
std::vector<std::vector<int>>mat{
{1,2},
{3,4,5,6},
{7,8,9}
};
int columns[3]={2,4,3};
try {
int ** dynamic_mat = Make2DStructure(mat);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < columns[i]; j++)
std::cout << dynamic_mat[i][j] << " ";
std::cout << std::endl;
}
delete[] dynamic_mat[0];
delete[] dynamic_mat;
} catch (...) {
std::cout << "Problems with memory";
}
return 0;
}
我如何修改它以在不在 Make2DStrucure()
中建立索引的情况下工作?
此外,如果我在 main 函数中使用 std::set<std::list<int>>
而不是 std::vector<std::vector<int>>
,我会遇到推导问题。我如何修改它以适用于不同的外部和内部容器?
这里有一种方法可以完成您想要的:
#include <iterator>
#include <type_traits>
template <typename tip>
auto Make2DStructure(tip&& mat) {
// create an alias for the value type:
using value_type = std::decay_t<decltype(*std::begin(*std::begin(mat)))>;
// allocate memory for the return value, the pointer-pointer:
value_type** rv = new value_type*[mat.size()]; // C++17: std::size(mat)
// Calculate the number of values we need to allocate space for:
size_t values = 0;
for(auto& inner: mat) values += inner.size(); // C++17: std::size(inner)
// allocate the space for the values:
value_type* data = new value_type[values];
// loop over the outer and inner container and keep the index running:
size_t idx = 0;
for(auto& inner : mat) {
// assign the outer pointer into the flat data block:
rv[idx++] = data;
for(auto& val : inner) {
// assign values in the data block:
*data++ = val;
}
}
return rv;
}
在指定的地方使用 std::size
,这也适用于普通数组,而不仅仅是容器 类。
我正在尝试制作一个动态分配二维结构的通用函数。每行中的元素数不必对所有行都相同。结构表示为容器类型,其元素也是容器类型(例如一组列表)。该内部容器的元素类型也可以是任意的。容器仅支持 begin、end 和 size 函数。所有迭代器类型都必须支持迭代器操作。函数应该首先通过连续分配过程动态分配用于存储二维结构的space,然后将其接受的结构的元素重写到动态结构中。函数 returns 一个双指针,通过它可以访问此结构的元素。
#include <iostream>
#include <set>
#include <list>
#include <vector>
template < typename tip >
auto Make2DStructure(tip mat) {
using tip_objekta = typename std::decay < decltype(mat[0][0]) > ::type;
tip_objekta ** dynamic_mat = nullptr;
int rows = 0, total = 0;
for (auto i: mat) {
rows++;
for (auto j: i)
total++;
}
int columns[rows];
int k = 0;
for (auto i: mat) {
int num_of_colums = 0;
for (auto j: i)
num_of_colums++;
columns[k] = num_of_colums;
k++;
}
try {
dynamic_mat = new tip_objekta * [rows];
dynamic_mat[0] = new tip_objekta[total];
for (int i = 1; i < rows; i++)
dynamic_mat[i] = dynamic_mat[i - 1] + columns[i];
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns[i]; j++)
dynamic_mat[i][j] = mat[i][j];
} catch (...) {
delete[] dynamic_mat[0];
delete[] dynamic_mat;
throw std::bad_alloc();
}
return dynamic_mat;
}
int main() {
std::vector<std::vector<int>>mat{
{1,2},
{3,4,5,6},
{7,8,9}
};
int columns[3]={2,4,3};
try {
int ** dynamic_mat = Make2DStructure(mat);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < columns[i]; j++)
std::cout << dynamic_mat[i][j] << " ";
std::cout << std::endl;
}
delete[] dynamic_mat[0];
delete[] dynamic_mat;
} catch (...) {
std::cout << "Problems with memory";
}
return 0;
}
我如何修改它以在不在 Make2DStrucure()
中建立索引的情况下工作?
此外,如果我在 main 函数中使用 std::set<std::list<int>>
而不是 std::vector<std::vector<int>>
,我会遇到推导问题。我如何修改它以适用于不同的外部和内部容器?
这里有一种方法可以完成您想要的:
#include <iterator>
#include <type_traits>
template <typename tip>
auto Make2DStructure(tip&& mat) {
// create an alias for the value type:
using value_type = std::decay_t<decltype(*std::begin(*std::begin(mat)))>;
// allocate memory for the return value, the pointer-pointer:
value_type** rv = new value_type*[mat.size()]; // C++17: std::size(mat)
// Calculate the number of values we need to allocate space for:
size_t values = 0;
for(auto& inner: mat) values += inner.size(); // C++17: std::size(inner)
// allocate the space for the values:
value_type* data = new value_type[values];
// loop over the outer and inner container and keep the index running:
size_t idx = 0;
for(auto& inner : mat) {
// assign the outer pointer into the flat data block:
rv[idx++] = data;
for(auto& val : inner) {
// assign values in the data block:
*data++ = val;
}
}
return rv;
}
在指定的地方使用 std::size
,这也适用于普通数组,而不仅仅是容器 类。