酷代码 AI
菜单

#include <iostream> #include <sstream> #include <string> #include <cctype> #include <vector> // 将字符串转换为小写 std::string toLowerCase(const std::string& str) { std::string result = str; for (char& c : result) { c = std::tolower(c); } return result; } int main() { std::string target; std::getline(std::cin, target); target = toLowerCase(target); std::string article; std::getline(std::cin, article); std::stringstream ss(article); std::vector<std::

以下对这两段代码进行综合分析,指出可能存在的问题以及改进方向。 代码功能 这两段代码的主要功能都是在一篇文章中查找指定单词出现的次数,并且记录该单词首次出现的位置,查找过程不区分大小写。第一段代码使用 C++ 编写,第二段代码使用 C 语言编写。 可能存在的问题及分析 第一段 C++ 代码 - 单词分割问题:代码使用 `std::stringstream` 按空格分割文章为单词,这种方式会忽略掉标点符号等其他分隔符,可能导致某些情况下无法正确识别单词。例如,“hello,world” 会被当作一个单词处理。 - 边界条件处理:代码在统计首次出现位置时,计算位置是基于单词数量累加单词长度和空格长度,可能在某些复杂的输入格式下出现计算错误。 第二段 C 代码 - 数组大小限制:代码中定义 `word` 数组大小为 100,`article` 数组大小为 1000000,对于输入的单词或文章过长时,可能会导致缓冲区溢出。 - 单词匹配问题:在判断是否为独立单词时,仅检查单词后面是否为空格或字符串结尾,对于文章结尾处的单词匹配可能存在问题。 改进建议 第一段 C++ 代码改进 ```cpp #include <iostream> #include <sstream> #include <string> #include <cctype> #include <vector> // 将字符串转换为小写 std::string toLowerCase(const std::string& str) { std::string result = str; for (char& c : result) { c = std::tolower(c); } return result; } int main() { std::string target; std::getline(std::cin, target); target = toLowerCase(target); std::string article; std::getline(std::cin, article); int count = 0; int firstPos = -1; int currentPos = 0; for (size_t i = 0; i < article.length(); ) { // 跳过前导空格 while (i < article.length() && std::isspace(article[i])) { ++i; ++currentPos; } size_t start = i; // 找到单词结束位置 while (i < article.length() && !std::isspace(article[i])) { ++i; } std::string word = article.substr(start, i - start); std::string lowerWord = toLowerCase(word); if (lowerWord == target) { if (count == 0) { firstPos = currentPos; } ++count; } currentPos = i + 1; } if (count > 0) { std::cout << count << " " << firstPos << std::endl; } else { std::cout << -1 << std::endl; } return 0; } ``` 改进说明: - 直接遍历文章字符串,按空格分割单词,避免了 `std::stringstream` 分割带来的问题。 - 手动处理单词的起始和结束位置,确保位置计算的准确性。 第二段 C 代码改进 ```c #include <stdio.h> #include <string.h> #include <ctype.h> // 将字符串转换为小写 void toLowerCase(char *str) { for (int i = 0; str[i]; i++) { str[i] = tolower(str[i]); } } int main() { char word[1000000], article[1000000]; // 读取要查找的单词 if (scanf("%999999s", word) != 1) { return 1; } // 消耗掉scanf后的换行符 getchar(); // 读取文章内容 if (fgets(article, sizeof(article), stdin) == NULL) { return 1; } // 去掉fgets可能读取的换行符 article[strcspn(article, "\n")] = 0; // 将单词和文章都转换为小写,以实现不区分大小写的匹配 toLowerCase(word); toLowerCase(article); int wordLen = strlen(word); int count = 0; int firstPos = -1; int pos = 0; while (article[pos]) { // 跳过前导空格 while (article[pos] == ' ') { pos++; } // 如果到达字符串末尾则结束循环 if (!article[pos]) { break; } // 检查是否匹配目标单词 if (strncmp(article + pos, word, wordLen) == 0) { // 检查是否为独立单词 if (article[pos + wordLen] == ' ' || article[pos + wordLen] == '\0') { if (count == 0) { firstPos = pos; } count++; } } // 移动到下一个单词起始位置 while (article[pos] && article[pos] != ' ') { pos++; } } if (count > 0) { printf("%d %d\n", count, firstPos); } else { printf("-1\n"); } return 0; } ``` 改进说明: - 增大 `word` 和 `article` 数组的大小,减少缓冲区溢出的风险。 - 在 `scanf` 读取单词时,使用 `%999999s` 限制读取长度,避免缓冲区溢出。 通过以上改进,代码的健壮性和准确性应该会有所提高。你可以使用更多的测试用例进行验证。 [2025-12-15 17:32:28 | AI问答 | 1381点数解答]

服务商
相关提问
发财导航,免费问AI
实用工具查看更多