提问人:Someone Someone 提问时间:11/8/2023 最后编辑:Someone Someone 更新时间:11/10/2023 访问量:84
在二维数组中搜索字符组合的代码不输出任何内容
Code to search for combinations of characters in a two-dimensional array doesn't output anything
问:
如果此代码首先采用一行字符组合的输入,每个字符由空格分隔,然后不超过 10 行输入,所有输入的长度相等但不超过 10 个字符,然后从二维数组中的第一行搜索字符组合。这是代码。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#define WORDNUM 100
#define SIZE 10
int getWords(char wordMatrix[WORDNUM][100]){
char c;
int i=0, j=0;
while ((c=fgetc(stdin)) != '\n'){
if (isalpha(c)){
wordMatrix[i][j]=c;
j++;
}
else if(c==' '){
i++;
j=0;
}
}
return i+1;
}
int getMatrix( char matrix[SIZE][SIZE]){
char c;
int i=0, j;
while ((c=fgetc(stdin)) != EOF && i < (SIZE)){
if (isalpha(c)){
matrix[i][j]=c;
j++;
}
else if(c=='\n'){
i++;
j=0;
}
}
return i;
}
int checkExist(int rowM , int xM, int rowNum, int rowLen, char *word, char matrix[SIZE][SIZE]){
int xW=1;
int direction;
direction = -1;
while((rowM + direction) > 0){
if(matrix[xM][rowM+direction] == word[xW]){
xW++;
if(xW == strlen(word)) return 1;
else direction--;
}
else break;
}
direction = -1;
while((xM + direction) > 0){
if(matrix[xM+direction][rowM] == word[xW]){
xW++;
if(xW == strlen(word)) return 1;
else direction--;
}
else break;
}
direction = 1;
while((rowM + direction) < rowNum){
if(matrix[xM][rowM+direction] == word[xW]){
xW++;
if(xW == strlen(word)) return 1;
else direction++;
}
else break;
}
direction = 1;
while((xM + direction) < rowLen ){
if(matrix[xM+direction][rowM] == word[xW]){
xW++;
if(xW == strlen(word)) return 1;
else direction++;
}
else break;
}
return 0;
}
int checkMatrix(int rowNum, int rowLen, char *word, char matrix[SIZE][SIZE]){
int xM, rowM, check;
for(rowM=0; rowM < rowNum; rowM++){
for(xM=0; xM < rowLen; xM++){
if(word[0] == matrix[rowM][xM]){
if(strlen(word) == 1) return 1;
else if (strlen(word)>1 && (check = checkExist(rowM, xM, rowNum, rowLen, word, matrix)) == 1) return 1;
}
}
}
return 0;
}
int main() {
char word[WORDNUM][100], matrix[SIZE][SIZE];
int logRowNumW, logRowNumM, logRowLen, rowW, x, check;
logRowNumW = getWords(word);
logRowNumM = getMatrix(matrix);
logRowLen = strlen(matrix[0]);
for(rowW=0; rowW <logRowNumW; rowW++){
if((check = checkMatrix(logRowNumM, logRowLen, word[rowW], matrix)) == 1){
for(x=0; x<strlen(word[rowW]); x++){
printf("%c", word[rowW][x]);
}
}
}
return 0;
}
问题是,它不会输出任何内容,无论是正确的还是不正确的,什么都没有。感谢您的任何建议
编辑:事实证明,两个愚蠢的错误是错误的。首先,xW ins在checkExist中没有重置每个方向,其次,我在checkExist中混淆了xM和rowM,它现在运行良好。
答:
getWords()
, : 返回一个 (不是 ),当您检查 时,这一点尤为重要。getMatrix()
fgetc()
int
char
EOF
getMatrix()
getWords()
, : 您不会以“\0”终止或终止,因此任何依赖于这些字符串(即)的东西都会触发未定义的行为。getMatrix()
wordMatrix
matrix
strlen()
getWords()
可能应该跳过前导空格。getMatrix()
您需要初始化 .j
(不固定)为第二个 100 幻值引入一个MAX_WORD_LEN或类似值,并在遍历矩阵时使用该上限以避免缓冲区溢出。或者考虑使用动态分配输入空间。
getline()
(不固定)请考虑用于将字符串解析为单词。请注意,它会更改输入字符串,这需要做更多的工作,但可以用来定位分隔符,但您确实需要自己处理初始、连续和尾随分隔符。
strtok()
strpbrk()
strch()
通过最初的 4 项更改:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#define WORDNUM 100
#define SIZE 10
int getWords(char wordMatrix[WORDNUM][100]){
int c;
int i=0, j=0;
while ((c=fgetc(stdin)) != '\n') {
if (isalpha(c)){
wordMatrix[i][j]=c;
j++;
} if(c==' ') {
if(!j) continue;
wordMatrix[i][j] = '\0';
i++;
j=0;
}
}
wordMatrix[i][j] = '\0';
return i+1;
}
int getMatrix( char matrix[SIZE][SIZE]){
int c;
int i=0, j = 0;
while ((c=fgetc(stdin)) != EOF && i < (SIZE)){
if (isalpha(c)){
matrix[i][j]=c;
j++;
}
else if(c=='\n'){
matrix[i][j] = '\0';
i++;
j=0;
}
}
// If last line can be terminated with EOF instead of \n
// then you need another '\0':
// matrix[i][j] = '\0';
return i;
}
int checkExist(int rowM , int xM, int rowNum, int rowLen, char *word, char matrix[SIZE][SIZE]){
int xW=1;
int direction;
direction = -1;
while((rowM + direction) > 0){
if(matrix[xM][rowM+direction] == word[xW]){
xW++;
if(xW == strlen(word)) return 1;
else direction--;
}
else break;
}
direction = -1;
while((xM + direction) > 0){
if(matrix[xM+direction][rowM] == word[xW]){
xW++;
if(xW == strlen(word)) return 1;
else direction--;
}
else break;
}
direction = 1;
while((rowM + direction) < rowNum){
if(matrix[xM][rowM+direction] == word[xW]){
xW++;
if(xW == strlen(word)) return 1;
else direction++;
}
else break;
}
direction = 1;
while((xM + direction) < rowLen ){
if(matrix[xM+direction][rowM] == word[xW]){
xW++;
if(xW == strlen(word)) return 1;
else direction++;
}
else break;
}
return 0;
}
int checkMatrix(int rowNum, int rowLen, char *word, char matrix[SIZE][SIZE]){
for(int rowM=0; rowM < rowNum; rowM++){
for(int xM=0; xM < rowLen; xM++){
if(word[0] == matrix[rowM][xM]){
if(strlen(word) == 1) return 1;
else if (strlen(word)>1 && (checkExist(rowM, xM, rowNum, rowLen, word, matrix) == 1)) return 1;
}
}
}
return 0;
}
int main() {
char word[WORDNUM][100], matrix[SIZE][SIZE];
int logRowNumW = getWords(word);
int logRowNumM = getMatrix(matrix);
int logRowLen = strlen(matrix[0]);
for(int rowW=0; rowW <logRowNumW; rowW++){
if((checkMatrix(logRowNumM, logRowLen, word[rowW], matrix)) == 1){
for(int x=0; x<strlen(word[rowW]); x++){
printf("%c", word[rowW][x]);
}
}
}
return 0;
}
您的程序现在生成输出:
a
ab
cd
<EOF>
a
在注释中使用提供的输入(我认为)是我编写硬编码测试用例并按照注释中讨论的行修改代码的方式:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#define N 10
#define NORTH {-1, 0}
#define EAST {0, 1}
#define SOUTH {1, 0}
#define WEST {0, -1}
int checkExist(int r, int c, int m, int n, const char *word, const char matrix[][N]) {
if(word[0] != matrix[r][c])
return 0;
const int directions[][2] = { NORTH, EAST, SOUTH, WEST };
for(int d = 0; d < sizeof directions / sizeof *directions; d++) {
int w = 1;
for(int r2 = r + directions[d][0], c2 = c + directions[d][1]; r2 >= 0 && r2 < m && c2 >= 0 && c2 < n && word[w]; r2 += directions[d][0], c2 += directions[d][1], w++)
if(word[w] != matrix[r2][c2])
break;
if(!word[w])
return 1;
}
return 0;
}
int checkMatrix(int m, int n, const char *word, const char matrix[][N]){
for(int r=0; r < m; r++)
for(int c=0; c < n; c++)
if(checkExist(r, c, m, n, word, matrix))
return 1;
return 0;
}
int main(void) {
char *word[] = {
"oh",
"to",
"lot",
"kol",
"lok",
"tol",
"mol",
"ho",
"jol",
"loj",
"lol"
};
int words = sizeof word / sizeof *word;
char matrix[][N] = {
"john",
"moto",
"tolo"
};
int m = sizeof matrix / sizeof *matrix;
int n = strlen(matrix[0]);
for(int w=0; w < words; w++)
if((checkMatrix(m, n, word[w], matrix)))
printf("%s\n", word[w]);
}
这个非交互式程序返回:
oh
to
lot
tol
ho
我相信这是正确的输出。
如果匹配,那么也会。你可以预处理成一个数组,所以在上面。如果单词匹配,则还打印出相反的 if 为 true。word[w]
reverse(word[w])
word
struct { char *word, int has_reverse }
{ "oh", 1 }, { "to", 0 }, ...
has_reverse
评论
checkMatrix()
checkExists()
checkExist()
你有 essential 相同的代码重复 4 次。创建一个数组,其中包含要检查的每个方向 '{ {0, -1}, {0,1}, {-1,0}, {1, 0} }',然后遍历该数组。您唯一想要的调整是使用您现在拥有的类似代码检查行和列的上限和下限。
评论
char c;
fgetc()
int c;
strlen(word))
是 UB,因为 u 不是 null 字符。word
checkMatrix()
if checkMatrix() == 1
getWords()