问题是要找出一个单词在给定的N x N个字母矩阵中出现的次数。我们可以从任何一个单元移动到其他相邻的单元。第一行具有一个整数N,然后具有N x N矩阵。下一行具有M(字的大小),然后是要在矩阵中找到的字符串。
Input:
4
ABCD
ABCD
ABCD
ABCD
2
BC
Expected output:
10
我为相同的代码编写了以下代码,并使用了递归来解决问题。函数adj使用其索引检查字符在矩阵中是否与前一个字符相邻。每当字符串完成时,功能检查都会增加计数。二维数组会检查已访问和未访问的元素。
我得到的输出为
OUPUT
1
EDIT 1:此输出仅是由于调试print语句,因此if语句仅被访问一次。这并不意味着在多次递归调用之后count变量为1。
编辑2:在scanf语句中不应有&词。但是输出仍然不是想要的。
编辑3:
Another input
7
SHELDON
HSTYUPQ
EHGXBAJ
LMNNQQI
DTYUIOP
OZXCVBN
NQWERTY
7
SHELDON
Expected output:
5
My output - 1
编辑4(已解决!):所以问题出在写号。网格矩阵的列数为500,将其更改为5就可以了!感谢@gsamaras
代码
#include <stdio.h>
int vis[500][500], count;
int adj(int a, int b, int c, int d) {
if((c == a - 1) && (d == b - 1)) {
return 1;
}
else if((c == a - 1) && (d == b)) {
return 1;
}
else if((c == a) && (d == b - 1)) {
return 1;
}
else if((c == a - 1) && (d == b + 1)) {
return 1;
}
else if((c == a + 1) && (d == b)) {
return 1;
}
else if((c == a + 1) && (d == b + 1)) {
return 1;
}
else if((c == a) && (d == b + 1)) {
return 1;
}
else if((c == a + 1) && (d == b - 1)) {
return 1;
}
else {
return 0;
}
}
void check(char grid[][500],int i, int j, int id, char word[], int n, int m) {
if(id == m) {
count++;
printf("%d\n", count); // just to debug
}
else {
for(int p = 0; p < n; p++) {
for(int q = 0;q < n; q++) {
if((grid[p][q] == word[id]) && (adj(i, j, p, q)) && (vis[p][q] != 1)) {
vis[p][q] = 1;
check(grid, p, q, id + 1, word, n, m);
vis[p][q] = 0;
}
}
}
}
}
int main() {
int n, m, id = 0;
char blank;
scanf("%d", &n);
scanf("%c", &blank);
char grid[n][n+1];
for(int i = 0; i < n; i++) {
scanf("%s", grid[i]);
grid[i][n] = '\0';
}
scanf("%d", &m);
char word[m+1];
scanf("%s", &word);
for(int i = 0; i < n; i++) {
for(int j = 0;j < n; j++) {
if(grid[i][j] == word[id]) {
vis[i][j] = 1;
check(grid, i, j, id + 1, word, n, m);
vis[i][j] = 0;
}
}
}
printf("%d\n", count);
return 0;
}
答案 0 :(得分:2)
更改此:
void check(char grid[][500], ......
对此:
void check(char grid[][5], ....... // that should be equal to N + 1 (5 in your case)
由于网格的大小为N x N +1。使用500
作为维度,您使网格变形,并且当尝试递归搜索时,您将不会遍历网格。希望遍历。
如您所见,这并不灵活,因为N
可能会有所不同。您无法将grid
声明为全局变量,因为其尺寸是固定的。应该使用Dynamic memory allocation。
更改此:
scanf("%s", &word);
对此:
scanf("%s", word);
因为word
是一个字符数组。
带有动态内存分配的完整示例:
#include <stdio.h>
#include <stdlib.h>
int vis[500][500], count;
char **get(int N, int M) { /* Allocate the array */
int i;
char **p;
p = malloc(N*sizeof(char *));
for(i = 0 ; i < N ; i++)
p[i] = malloc( M*sizeof(char) );
return p;
}
void free2Darray(char** p, int N) {
int i;
for(i = 0 ; i < N ; i++)
free(p[i]);
free(p);
}
int adj(int a, int b, int c, int d) {
// Same as in your question
}
void check(char** grid, int i, int j, int id, char word[], int n, int m) {
if(id == m) {
count++;
printf("count = %d\n", count); // just to debug
}
else {
for(int p = 0; p < n; p++) {
for(int q = 0;q < 499; q++) {
//printf("p = %d, q = %d, id = %d, grid[p][q] = %c, word[id] = %c\n", p, q, id, grid[p][q], word[id]);
if((grid[p][q] == word[id]) && (adj(i, j, p, q)) && (vis[p][q] != 1)) {
vis[p][q] = 1;
check(grid, p, q, id + 1, word, n, m);
vis[p][q] = 0;
}
}
}
}
}
int main() {
int n, m, id = 0;
char blank;
scanf("%d", &n);
scanf("%c", &blank);
char** grid = get(n, n + 1);
for(int i = 0; i < n; i++) {
scanf("%s", grid[i]);
grid[i][n] = '\0';
}
scanf("%d", &m);
char word[m+1];
scanf("%s", word);
for(int i = 0; i < n; i++) {
for(int j = 0;j < n; j++) {
//printf("i = %d, j = %d, id = %d\n", i, j, id);
if(grid[i][j] == word[id]) {
vis[i][j] = 1;
check(grid, i, j, id + 1, word, n, m);
vis[i][j] = 0;
}
}
}
printf("%d\n", count);
free2Darray(grid, n);
return 0;
}
输出(用于您的第一个输入):
count = 1
count = 2
count = 3
count = 4
count = 5
count = 6
count = 7
count = 8
count = 9
count = 10
10
PS:没问题,只是关于可读性的建议:count
被初始化为0,因为it's a global variable,但是最好在需要时显式初始化变量。