如果我有一个如下所示的数组:
int map[21][28] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
如何创建一个由该数组内的值组成的较小数组。?
有点像这样:
int zoomedMap[7][7] =
{
2, 2, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1
};
我不知道这是否有帮助,但是:
答案 0 :(得分:1)
在希望显而易见的是,你的子阵列实际上只不过是一个"块" 主阵列中的数据(带有一些有趣的分区)假设您正在检查边界并且不允许发生越界条件,您可以使用指针数学和关于主阵列的一些基本信息来模拟子阵列。
[row][column]
位置偏移[0][0]
,因此我们需要这些值(行和列)。column+width
不超过主阵列宽度。我们需要那个宽度。row+height
不超过主阵列高度。我们需要那个高度。map
)。这可能是最好的例子。以下不是一些最终解决方案。它甚至可能无法解决您需要的1/10。相反,它旨在为您提供如何使用指针,一些偏移,一些大小和一些算术来实现这一点的想法,以获得您正在寻找的东西。没有没有阻止你超出可能有害的限制(就像普通阵列一样),所以要小心。
// internal rerefential to a submatrix in a larger fixed matrix.
template<typename T>
class Sub2D
{
public:
template<size_t R, size_t C>
Sub2D(T(&ar)[R][C], int top, int left, int height, int width)
: parent(ar[0])
, row(top)
, col(left)
, max_row(R)
, max_col(C)
{
if ((row+width) >= R || (col+height) >= C)
throw std::out_of_range("");
}
// retrieve our subrow offset into the main 2D array
T* operator [](size_t n)
{
// enable at your desire, but as Alex pointed out, all
// the standard containers let you shoot yourself in the
// foot with this operator. why not this one too =P
//if (row+n >= max_row)
// throw std::out_of_range("");
return parent + ((row+n)*max_col + col);
}
private:
T* parent;
size_t row, col;
size_t max_row, max_col;
};
像这样使用,假设你的问题中的数组是我们所基于的那个:
int main()
{
// take the submatrix & [6][7] that is 7x7 in dimension.
Sub2D<int> sub(map, 6,7, 7,7);
for (size_t i=0;i<7;++i)
{
for (size_t j=0;j<7;++j)
cout << sub[i][j] << ' ';
cout << endl;
}
cout << endl;
// update an element at location [1][1] of our sub-matrix.
sub[1][1] = 9;
// reprint the *entire* main array. it better have updated.
for (size_t i=0;i<sizeof(map)/sizeof(map[0]);++i)
{
for (size_t j=0;j<sizeof(map[0])/sizeof(map[0][0]);++j)
cout << map[i][j] << ' ';
cout << endl;
}
cout << endl;
return 0;
}
产生以下输出。
2 2 1 1 1 1 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 2 2 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 9 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
请注意9现在就在我们预期的位置。
显然你可以添加更多这样的模板类,包括更好的范围检查,移动指针,快照到其他内存缓冲区等,但重点是基本的get-me-this子矩阵指针和一些偏移很难被击败,特别是对于性能。
答案 1 :(得分:0)
阅读Boost的uBLAS模块。它提供了Matrix和MatrixRange类,这正是您正在寻找的。 p>
本质上,zoomedMap
应该只是一个指向更大矩阵的智能指针,它可以理解如何取消引用并获得正确的结果。
答案 2 :(得分:0)
你总是可以通过循环静态地完成它:
const int pos_x = 6, pos_y = 7, size_x = 7, size_y = 7;
int newMap[size_x][size_y] = {0};
for( int i = pos_x; i != pos_x+size_x; ++i ) {
for( int j = pos_y; j != pos_y+size_y; ++j) {
newMap[i-pos_x][j-pos_y] = map[i][j];
}
}
虽然这不是很安全,但很难动态地工作。 您可能希望编写一个包含所需函数的矩阵包装类;或找到一个已存在并扩展它(我开始研究现有矩阵类的STL或Boost)
答案 3 :(得分:0)
根据您的要求,这可能就足够了:
int (*zoomedMap)[28] = reinterpret_cast<int (*)[28]>(&map[X][Y]);
这为您提供了一个可以使用的标识符,就好像它是一个二维数组:zoomedMap[i][j]
。您可以通过为其指定新地址轻松移动较大阵列中的缩放地图。
这取决于你的C ++实现,允许指向float的指针被强制转换为指向float数组的指针,前提是所有引用都保留在原始数组中。这很常见。
它使zoomedMap
指向与map
相同的内存。因此,你不能在不改变另一个的情况下改变一个。如果你想这样做,你需要复制一份。