我只是通过递归对连接的组件标签进行编码 但是我想要使用堆栈和结构的非递归版本。
typedef struct _node{
int Xpos;
int Ypos;
int dir;
}node;
node *stack[MAX];
node *push(node *t) {
stack[++top] = t;
return t;
}
node *pop() {
return stack[top--];
}
结构组件确实具有Xposition和Yposition和Direction。 例如) if(t-> dir == 1){t-> Xpos = ++ t-> Xpos,t-> Ypos = --t-> Ypos}; 8邻居标签 我真的需要帮助! //编辑
//编辑 这是我通过递归所做的
#define MAP_SIZE 15
#define INILBCNT 10
int cnt = 1;
int input_map[MAP_SIZE][MAP_SIZE] =
{ {0,0,0,0,0,0,0,0,0,0,0,0,1,1,0},
{0,1,1,1,1,1,1,0,0,0,0,0,1,1,0},
{0,1,0,0,0,0,1,0,0,0,1,1,0,1,0},
{0,1,0,1,1,0,1,0,1,1,1,0,0,1,0},
{0,1,0,0,1,0,1,0,1,0,0,0,0,1,0},
{0,1,1,0,1,0,1,0,1,0,0,1,0,1,0},
{0,0,0,1,1,0,1,0,1,0,1,1,0,1,0},
{0,1,0,1,1,0,1,0,1,0,1,0,0,1,0},
{0,1,0,0,0,0,0,0,1,0,1,0,0,1,0},
{0,1,0,0,0,0,0,1,1,0,1,0,0,1,0},
{0,1,1,1,1,1,0,1,0,0,1,1,0,1,0},
{0,0,0,0,0,1,0,1,0,1,0,0,0,1,0},
{0,1,1,1,0,1,0,1,0,0,0,0,0,1,0},
{0,1,0,0,0,1,0,1,1,1,1,1,1,1,0},
{0,1,1,1,1,1,0,0,0,0,0,0,0,1,0}
};
void PrintMap()
{
system("cls");
for (int j = 0; j < MAP_SIZE; j++)
{
for (int i = 0; i < MAP_SIZE; i++)
{
printf("%d ", input_map[j][i]);
}
printf("\n"); } }
void glassFire(int mask_Y, int mask_X)
{
if (input_map[mask_Y][mask_X] != 1)
return;
else
if (input_map[mask_Y][mask_X] == 1)
{
input_map[mask_Y][mask_X] = cnt;
glassFire(mask_Y, mask_X + 1);
glassFire(mask_Y + 1, mask_X);
glassFire(mask_Y + 1, mask_X + 1);
glassFire(mask_Y + 1, mask_X - 1);
glassFire(mask_Y - 1, mask_X + 1);
glassFire(mask_Y - 1, mask_X);
glassFire(mask_Y - 1, mask_X + 1);
glassFire(mask_Y, mask_X - 1); }}
void Serching()
{
PrintMap();
for (int i = 0; i < MAP_SIZE; i++)
{
for (int j = 0; j < MAP_SIZE; j++)
{
if (input_map[j][i] == 1)
{
cnt++;
glassFire(j, i);}
}
}
}
这段代码很好用。
答案 0 :(得分:2)
这段代码很好用。
否,此代码具有未定义的行为,因为由于递归调用的添加/删除,您在input_map
和/或mask_Y
中读/写时mask_X
和/或mask_Y
的值为-1和/或15 1至mask_X
/ void glassFire(int mask_Y, int mask_X)
{
if (input_map[mask_Y][mask_X] != 1)
return;
else
if (input_map[mask_Y][mask_X] == 1)
{
...
}
}
在
void glassFire(int mask_Y, int mask_X) { if ((mask_Y >= 0) && (mask_X >= 0) && (mask_Y < MAP_SIZE) && (mask_X < MAP_SIZE) && (input_map[mask_Y][mask_X] == 1)) { ... } }
第一个 if 没有用,但是您必须检查索引,可以是:
glassFire(mask_Y - 1, mask_X + 1);
您拨打两次glassFire(mask_Y - 1, mask_X - 1);
,一次必须用丢失的 glassFire(mask_Y, mask_X + 1);
glassFire(mask_Y + 1, mask_X);
glassFire(mask_Y + 1, mask_X + 1);
glassFire(mask_Y + 1, mask_X - 1);
glassFire(mask_Y - 1, mask_X + 1);
glassFire(mask_Y - 1, mask_X);
glassFire(mask_Y - 1, mask_X - 1); /* modified */
glassFire(mask_Y, mask_X - 1); }}
代替。
而不是做
static const YX offset[] = { {0,1}, {1,0}, {1,1}, {1,-1}, {-1,1}, {-1,0}, {-1,-1}, {0,-1} }; for (int dir = 0; dir != 8; ++dir) glassFire(mask_Y + offset[dir].y, mask_X + offset[dir].x);
您可以使用循环(这将有助于手动管理递归,减少代码量):
typedef struct YX { int y; int x; } YX;
与void glassFire(int mask_Y, int mask_X)
{
YX * stack = NULL;
size_t sz = 0;
size_t deep = 0;
for (;;) {
if (input_map[mask_Y][mask_X] == 1) /* need to check, can be false now */
{
input_map[mask_Y][mask_X] = cnt;
static const YX offset[] = {
{0,1}, {1,0}, {1,1}, {1,-1}, {-1,1}, {-1,0}, {-1,-1}, {0,-1}
};
/* up to 8 positions to save */
if ((deep + 8) > sz) {
sz += 8;
stack = realloc(stack, sz * sizeof(YX));
}
for (int dir = 0; dir != 8; ++dir) {
int ny = mask_Y + offset[dir].y;
int nx = mask_X + offset[dir].x;
if ((ny >= 0) && (nx >= 0) &&
(ny < MAP_SIZE) && (nx < MAP_SIZE) &&
(input_map[ny][nx] == 1))
{
stack[deep].y = ny;
stack[deep].x = nx;
deep += 1;
}
}
}
if (deep == 0)
/* empty */
break;
deep -= 1;
mask_Y = stack[deep].y;
mask_X = stack[deep].x;
}
free(stack);
}
要删除递归调用,您的包含方向的结构是不合适的,因为递归调用可以执行其他递归调用等,您只需要保存以后要管理的索引即可。
幸运的是,结果不取决于递归调用的顺序。
解决方案可以是:
#include <stdio.h>
#include <stdlib.h>
#define MAP_SIZE 15
int cnt = 1;
int input_map[MAP_SIZE][MAP_SIZE] =
{ {0,0,0,0,0,0,0,0,0,0,0,0,1,1,0},
{0,1,1,1,1,1,1,0,0,0,0,0,1,1,0},
{0,1,0,0,0,0,1,0,0,0,1,1,0,1,0},
{0,1,0,1,1,0,1,0,1,1,1,0,0,1,0},
{0,1,0,0,1,0,1,0,1,0,0,0,0,1,0},
{0,1,1,0,1,0,1,0,1,0,0,1,0,1,0},
{0,0,0,1,1,0,1,0,1,0,1,1,0,1,0},
{0,1,0,1,1,0,1,0,1,0,1,0,0,1,0},
{0,1,0,0,0,0,0,0,1,0,1,0,0,1,0},
{0,1,0,0,0,0,0,1,1,0,1,0,0,1,0},
{0,1,1,1,1,1,0,1,0,0,1,1,0,1,0},
{0,0,0,0,0,1,0,1,0,1,0,0,0,1,0},
{0,1,1,1,0,1,0,1,0,0,0,0,0,1,0},
{0,1,0,0,0,1,0,1,1,1,1,1,1,1,0},
{0,1,1,1,1,1,0,0,0,0,0,0,0,1,0}
};
void PrintMap()
{
for (int j = 0; j < MAP_SIZE; j++)
{
for (int i = 0; i < MAP_SIZE; i++)
{
printf("%d ", input_map[j][i]);
}
putchar('\n');
}
}
typedef struct YX { int y; int x; } YX;
void glassFire(int mask_Y, int mask_X)
{
YX * stack = NULL;
size_t sz = 0;
size_t deep = 0;
for (;;) {
if (input_map[mask_Y][mask_X] == 1)
{
input_map[mask_Y][mask_X] = cnt;
static const YX offset[] = {
{0,1}, {1,0}, {1,1}, {1,-1}, {-1,1}, {-1,0}, {-1,-1}, {0,-1}
};
/* 8 positions to save */
if ((deep + 8) > sz) {
sz += 8;
stack = realloc(stack, sz * sizeof(YX));
}
for (int dir = 0; dir != 8; ++dir) {
int ny = mask_Y + offset[dir].y;
int nx = mask_X + offset[dir].x;
if ((ny >= 0) && (nx >= 0) &&
(ny < MAP_SIZE) && (nx < MAP_SIZE) &&
(input_map[ny][nx] == 1))
{
stack[deep].y = ny;
stack[deep].x = nx;
deep += 1;
}
}
}
if (deep == 0)
/* empty */
break;
deep -= 1;
mask_Y = stack[deep].y;
mask_X = stack[deep].x;
}
free(stack);
}
void Serching() /* probably searching */
{
PrintMap();
for (int i = 0; i < MAP_SIZE; i++)
{
for (int j = 0; j < MAP_SIZE; j++)
{
if (input_map[j][i] == 1)
{
cnt++;
glassFire(j, i);}
}
}
}
int main()
{
Serching();
putchar('\n');
PrintMap();
}
如果我使用该完整程序(我删除了无用的 INILBCN ):
pi@raspberrypi:~ $ gcc -pedantic -Wall -Wextra c.c
pi@raspberrypi:~ $ ./a.out
0 0 0 0 0 0 0 0 0 0 0 0 1 1 0
0 1 1 1 1 1 1 0 0 0 0 0 1 1 0
0 1 0 0 0 0 1 0 0 0 1 1 0 1 0
0 1 0 1 1 0 1 0 1 1 1 0 0 1 0
0 1 0 0 1 0 1 0 1 0 0 0 0 1 0
0 1 1 0 1 0 1 0 1 0 0 1 0 1 0
0 0 0 1 1 0 1 0 1 0 1 1 0 1 0
0 1 0 1 1 0 1 0 1 0 1 0 0 1 0
0 1 0 0 0 0 0 0 1 0 1 0 0 1 0
0 1 0 0 0 0 0 1 1 0 1 0 0 1 0
0 1 1 1 1 1 0 1 0 0 1 1 0 1 0
0 0 0 0 0 1 0 1 0 1 0 0 0 1 0
0 1 1 1 0 1 0 1 0 0 0 0 0 1 0
0 1 0 0 0 1 0 1 1 1 1 1 1 1 0
0 1 1 1 1 1 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 4 4 0
0 2 2 2 2 2 2 0 0 0 0 0 4 4 0
0 2 0 0 0 0 2 0 0 0 4 4 0 4 0
0 2 0 2 2 0 2 0 4 4 4 0 0 4 0
0 2 0 0 2 0 2 0 4 0 0 0 0 4 0
0 2 2 0 2 0 2 0 4 0 0 5 0 4 0
0 0 0 2 2 0 2 0 4 0 5 5 0 4 0
0 3 0 2 2 0 2 0 4 0 5 0 0 4 0
0 3 0 0 0 0 0 0 4 0 5 0 0 4 0
0 3 0 0 0 0 0 4 4 0 5 0 0 4 0
0 3 3 3 3 3 0 4 0 0 5 5 0 4 0
0 0 0 0 0 3 0 4 0 5 0 0 0 4 0
0 3 3 3 0 3 0 4 0 0 0 0 0 4 0
0 3 0 0 0 3 0 4 4 4 4 4 4 4 0
0 3 3 3 3 3 0 0 0 0 0 0 0 4 0
编译和执行:
cnt
我将input_map
和{{1}}设为全局,但是它们可以位于 Serching 中,并可以为 glassFire 提供参数。全局变量越少越好。
请注意,我的代码产生的结果与您的代码(对校正结果取模)相同,但我不知道您的代码是否正确,因为我不知道它的真正作用是什么;-)