检查动态分配的二维数组中的相邻单元格
Checking neighboring cells in a dynamically allocated 2D array
我正在开展一个项目,我需要检查动态分配的二维 char
数组中特定单元格的相邻单元格。基本上,例如,如果某些相邻单元格是 'X'
,那么您所在的当前单元格将变为 '-'
。为了分配二维数组,我使用了一个 malloc
调用:
char *array = (char *)malloc(numRows * numCols * sizeof(char));
要在使用双循环时访问元素,我使用这个:
for (int i = 0; i <= getNumRows(); i++)
{
for (int j = 0; j < getNumCols(); j++)
{
printf("%c ", **(array + i * getNumCols() + j));
}
printf("\n");
}
如何访问和查看当前元素的相邻单元格?
我会使用指向数组的指针。它使数组索引更容易。示例打印相邻单元格。
void print_n(void *arr, size_t nrows, size_t ncols, size_t col, size_t row)
{
int (*array)[nrows][ncols] = arr;
if(col) printf("Left: %d\n", (*array)[row][col - 1]);
if(col < ncols - 1) printf("Right: %d\n", (*array)[row][col + 1]);
if(row) printf("Top: %d\n", (*array)[row - 1][col]);
if(row < nrows - 1) printf("Right: %d\n", (*array)[row + 1][col]);
}
int main(void)
{
size_t ncols = 10, nrows = 20;
int (*array)[nrows][ncols] = malloc(sizeof(*array));
for(size_t row = 0; row < nrows; row++)
for(size_t col = 0; col < ncols; col++)
(*array)[row][col] = row * 100 + col;
print_n(array, nrows, ncols, 6, 7);
free(array);
}
显示矩阵的代码有问题:
- 当
i == getNumRows()
和 时外循环应该停止
printf
参数应使用单个 *
解引用运算符
这是修改后的版本:
for (int i = 0; i < getNumRows(); i++) {
for (int j = 0; j < getNumCols(); j++) {
printf("%c ", *(array + i * getNumCols() + j));
}
printf("\n");
}
也可以重写以避免重复重新计算矩阵大小:
for (int i = 0, row = getNumRows(), cols = getNumCols(); i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%c ", array[i * cols + j]);
}
printf("\n");
}
访问单元格r,c
的相邻单元格取决于你如何处理边界:
- 如果不应跨越边界,则必须测试
r
and/or c
是否在边界上以产生 3 到 8 个邻居。
- 如果边界环绕成圆环,您只需计算
r+/-1 % rows
和 c+/-1 % cols
即可始终产生 8 个邻居。
为了简化第一种情况,您可以使用 char *array = malloc(sizeof(char) * (numRows + 1) * (numCols + 2));
为矩阵分配 2 个额外的列和行,并以这种方式使用内部 space(活动区域):
for (int i = 1; i <= getNumRows(); i++) {
for (int j = 1; j <= getNumCols(); j++) {
printf("%c ", *(array + i * getNumCols() + j));
}
printf("\n");
}
如果您将矩阵中的边界行和列初始化为 ' '
,您始终可以访问 r+/-1, c+/-1
处的 8 个单元格并检查 'X'
而无需对边界行进行特殊封装活跃部分。
可以根据实现选择来访问这些相邻小区:
int rows = getNumRows(), cols = getNumCols();
char *cellp = array + r * cols + c;
// using extra rows and columns
char top_1 = cellp[-cols - 1];
char top_2 = cellp[-cols];
char top_3 = cellp[-cols + 1];
char mid_1 = cellp[-1];
char mid_2 = cellp[+1];
char bot_1 = cellp[+cols - 1];
char bot_2 = cellp[+cols];
char bot_3 = cellp[+cols + 1];
// using torus-like wrapping
char top_1 = array[(r + rows - 1) % rows * cols + (c + cols - 1) % cols];
char top_2 = array[(r + rows - 1) % rows * cols + c];
char top_3 = array[(r + rows - 1) % rows * cols + (c + 1) % cols];
char mid_1 = array[r * cols + (c + cols - 1) % cols];
char mid_2 = array[r * cols + (c + 1)];
char bot_1 = array[(r + 1) % rows * cols + (c + cols - 1) % cols];
char bot_2 = array[(r + 1) % rows * cols + c];
char bot_3 = array[(r + 1) % rows * cols + (c + 1) % cols];
// using tests
char top_1 = (r == 0 || c == 0 ) ? 0 : cellp[-cols - 1];
char top_2 = (r == 0 ) ? 0 : cellp[-cols];
char top_3 = (r == 0 || c == cols - 1) ? 0 : cellp[-cols + 1];
char mid_1 = ( c == 0 ) ? 0 : cellp[-1];
char mid_2 = ( c == cols - 1) ? 0 : cellp[+1];
char bot_1 = (r == rows - 1 || c == 0 ) ? 0 : cellp[+cols - 1];
char bot_2 = (r == rows - 1 ) ? 0 : cellp[+cols];
char bot_3 = (r == rows - 1 || c == cols - 1) ? 0 : cellp[+cols + 1];
我正在开展一个项目,我需要检查动态分配的二维 char
数组中特定单元格的相邻单元格。基本上,例如,如果某些相邻单元格是 'X'
,那么您所在的当前单元格将变为 '-'
。为了分配二维数组,我使用了一个 malloc
调用:
char *array = (char *)malloc(numRows * numCols * sizeof(char));
要在使用双循环时访问元素,我使用这个:
for (int i = 0; i <= getNumRows(); i++)
{
for (int j = 0; j < getNumCols(); j++)
{
printf("%c ", **(array + i * getNumCols() + j));
}
printf("\n");
}
如何访问和查看当前元素的相邻单元格?
我会使用指向数组的指针。它使数组索引更容易。示例打印相邻单元格。
void print_n(void *arr, size_t nrows, size_t ncols, size_t col, size_t row)
{
int (*array)[nrows][ncols] = arr;
if(col) printf("Left: %d\n", (*array)[row][col - 1]);
if(col < ncols - 1) printf("Right: %d\n", (*array)[row][col + 1]);
if(row) printf("Top: %d\n", (*array)[row - 1][col]);
if(row < nrows - 1) printf("Right: %d\n", (*array)[row + 1][col]);
}
int main(void)
{
size_t ncols = 10, nrows = 20;
int (*array)[nrows][ncols] = malloc(sizeof(*array));
for(size_t row = 0; row < nrows; row++)
for(size_t col = 0; col < ncols; col++)
(*array)[row][col] = row * 100 + col;
print_n(array, nrows, ncols, 6, 7);
free(array);
}
显示矩阵的代码有问题:
- 当
i == getNumRows()
和 时外循环应该停止
printf
参数应使用单个*
解引用运算符
这是修改后的版本:
for (int i = 0; i < getNumRows(); i++) {
for (int j = 0; j < getNumCols(); j++) {
printf("%c ", *(array + i * getNumCols() + j));
}
printf("\n");
}
也可以重写以避免重复重新计算矩阵大小:
for (int i = 0, row = getNumRows(), cols = getNumCols(); i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%c ", array[i * cols + j]);
}
printf("\n");
}
访问单元格r,c
的相邻单元格取决于你如何处理边界:
- 如果不应跨越边界,则必须测试
r
and/orc
是否在边界上以产生 3 到 8 个邻居。 - 如果边界环绕成圆环,您只需计算
r+/-1 % rows
和c+/-1 % cols
即可始终产生 8 个邻居。
为了简化第一种情况,您可以使用 char *array = malloc(sizeof(char) * (numRows + 1) * (numCols + 2));
为矩阵分配 2 个额外的列和行,并以这种方式使用内部 space(活动区域):
for (int i = 1; i <= getNumRows(); i++) {
for (int j = 1; j <= getNumCols(); j++) {
printf("%c ", *(array + i * getNumCols() + j));
}
printf("\n");
}
如果您将矩阵中的边界行和列初始化为 ' '
,您始终可以访问 r+/-1, c+/-1
处的 8 个单元格并检查 'X'
而无需对边界行进行特殊封装活跃部分。
可以根据实现选择来访问这些相邻小区:
int rows = getNumRows(), cols = getNumCols();
char *cellp = array + r * cols + c;
// using extra rows and columns
char top_1 = cellp[-cols - 1];
char top_2 = cellp[-cols];
char top_3 = cellp[-cols + 1];
char mid_1 = cellp[-1];
char mid_2 = cellp[+1];
char bot_1 = cellp[+cols - 1];
char bot_2 = cellp[+cols];
char bot_3 = cellp[+cols + 1];
// using torus-like wrapping
char top_1 = array[(r + rows - 1) % rows * cols + (c + cols - 1) % cols];
char top_2 = array[(r + rows - 1) % rows * cols + c];
char top_3 = array[(r + rows - 1) % rows * cols + (c + 1) % cols];
char mid_1 = array[r * cols + (c + cols - 1) % cols];
char mid_2 = array[r * cols + (c + 1)];
char bot_1 = array[(r + 1) % rows * cols + (c + cols - 1) % cols];
char bot_2 = array[(r + 1) % rows * cols + c];
char bot_3 = array[(r + 1) % rows * cols + (c + 1) % cols];
// using tests
char top_1 = (r == 0 || c == 0 ) ? 0 : cellp[-cols - 1];
char top_2 = (r == 0 ) ? 0 : cellp[-cols];
char top_3 = (r == 0 || c == cols - 1) ? 0 : cellp[-cols + 1];
char mid_1 = ( c == 0 ) ? 0 : cellp[-1];
char mid_2 = ( c == cols - 1) ? 0 : cellp[+1];
char bot_1 = (r == rows - 1 || c == 0 ) ? 0 : cellp[+cols - 1];
char bot_2 = (r == rows - 1 ) ? 0 : cellp[+cols];
char bot_3 = (r == rows - 1 || c == cols - 1) ? 0 : cellp[+cols + 1];