多同优先级if语句搭配else终止循环及二维数组单词搜索实现咨询
解决二维字符数组中水平/垂直单词搜索的问题
先明确核心需求:在每行等长的二维字符数组里匹配指定单词,仅支持水平(正向)或垂直(正向)排列,排除对角线;需处理字母重复场景,且所有匹配条件不满足时终止对应循环。
原代码的核心问题
- 变量未初始化:
while(a=1)里的a未初始化就赋值,属于未定义行为,直接用while(1)更稳妥。 - 字符串无终止符:读取单词时只存储字母,未添加
\0,后续字符串比较、长度计算会出错。 - 索引逻辑错误:内层循环误用
logLength[mLine](矩阵行长度),实际应该用logLength[wLine](当前待匹配单词的长度)。 - 缺失搜索逻辑:未实现水平、垂直方向的匹配逻辑,也没做边界检查,容易导致数组越界。
- 循环终止逻辑缺失:找到匹配后未及时跳出循环,会重复检查;也没标记已找到的单词,浪费资源。
- 矩阵换行符未处理:
fgets会把换行符读入矩阵,导致行长度计算错误,影响匹配准确性。
修正后的完整代码
#include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h> #define WORDNUM 100 #define MAX_MATRIX_ROWS 10 #define MAX_MATRIX_COLS 10 int main() { char c, word[WORDNUM][100], matrix[MAX_MATRIX_ROWS][MAX_MATRIX_COLS + 1]; int i = 0, j = 0, lineNum = 0, lineLen; int logLength[WORDNUM], logExist[WORDNUM] = {0}; int mLine, mLet, wLet, wLine; // 读取待搜索单词,统一转小写并补终止符 while (1) { c = fgetc(stdin); if (isalpha(c)) { word[i][j] = tolower(c); j++; } else if (c == ' ' || c == '\n') { if (j > 0) { word[i][j] = '\0'; logLength[i] = j; i++; j = 0; } if (c == '\n') break; } } int totalWords = i; // 读取矩阵并去除换行符 while (fgets(matrix[lineNum], MAX_MATRIX_COLS + 2, stdin) != NULL && lineNum < MAX_MATRIX_ROWS) { size_t len = strlen(matrix[lineNum]); if (len > 0 && matrix[lineNum][len - 1] == '\n') { matrix[lineNum][len - 1] = '\0'; } lineNum++; } if (lineNum == 0) { printf("矩阵为空,程序退出。\n"); return 0; } lineLen = strlen(matrix[0]); // 遍历矩阵每个字符作为起始点,匹配单词 for (mLine = 0; mLine < lineNum; mLine++) { for (mLet = 0; mLet < lineLen; mLet++) { char currentChar = tolower(matrix[mLine][mLet]); wLine = 0; while (wLine < totalWords) { if (logExist[wLine]) { wLine++; continue; } if (currentChar == word[wLine][0]) { int found = 0; // 检查水平向右方向 if (mLet + logLength[wLine] <= lineLen) { found = 1; for (wLet = 1; wLet < logLength[wLine]; wLet++) { if (tolower(matrix[mLine][mLet + wLet]) != word[wLine][wLet]) { found = 0; break; } } } // 水平未找到,检查垂直向下方向 if (!found && mLine + logLength[wLine] <= lineNum) { found = 1; for (wLet = 1; wLet < logLength[wLine]; wLet++) { if (tolower(matrix[mLine + wLet][mLet]) != word[wLine][wLet]) { found = 0; break; } } } // 匹配成功则标记并输出位置 if (found) { logExist[wLine] = 1; printf("找到单词 '%s',起始位置:行%d,列%d\n", word[wLine], mLine, mLet); } } wLine++; } } } // 输出未找到的单词 printf("\n未找到的单词:\n"); for (wLine = 0; wLine < totalWords; wLine++) { if (!logExist[wLine]) { printf("%s\n", word[wLine]); } } return 0; }
关键改进说明
- 统一大小写:将输入的单词和矩阵字符都转为小写,避免大小写不匹配导致的匹配失败。
- 边界检查:每次匹配前先判断单词长度是否超出矩阵边界,彻底杜绝数组越界访问。
- 效率优化:已找到的单词直接跳过,避免重复检查;每个方向匹配失败后立即终止该方向循环。
- 字符串完整性:读取单词后手动添加
\0,确保所有字符串操作正常。 - 矩阵格式修正:去除
fgets读入的换行符,保证矩阵每行长度准确。
内容的提问来源于stack exchange,提问作者Someone Someone
相关产品推荐
相关产品推荐

