曾彪彪的个人网站
首页
文章列表
>>
文章详情
单词统计错误解法
作者:
曾彪彪
日期:
2025-06-17 08:00:40
阅读(327)
分类:
问题记录
Algorithm
# P1308 [NOIP 2011 普及组] 统计单词数 ## 题目描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数。 现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意:匹配单词时,不区分大小写,但要求完全匹配,即给定单词必须与文章中的某一独立单词在不区分大小写的情况下完全相同(参见样例 1),如果给定单词仅是文章中某一单词的一部分则不算匹配(参见样例 2)。 ## 输入格式 共 $2$ 行。 第 $1$ 行为一个字符串,其中只含字母,表示给定单词; 第 $2$ 行为一个字符串,其中只可能包含字母和空格,表示给定的文章。 ## 输出格式 一行,如果在文章中找到给定单词则输出两个整数,两个整数之间用一个空格隔开,分别是单词在文章中出现的次数和第一次出现的位置(即在文章中第一次出现时,单词首字母在文章中的位置,位置从 $0$ 开始);如果单词在文章中没有出现,则直接输出一个整数 $-1$。 注意:空格占一个字母位 ## 输入输出样例 #1 ### 输入 #1 ``` To to be or not to be is a question ``` ### 输出 #1 ``` 2 0 ``` ## 输入输出样例 #2 ### 输入 #2 ``` to Did the Ottoman Empire lose its power at that time ``` ### 输出 #2 ``` -1 ``` ## 说明/提示 数据范围 $1\leq $ 第一行单词长度 $\leq10$。 $1\leq $ 文章长度 $\leq10^6$。 noip2011 普及组第 2 题 ## 错误解法 ```c++ #include <bits/stdc++.h> using namespace std; void toLower(string &s) { for (int i = 0; i < s.size(); i++) { s[i] = tolower(s[i]); } } int main() { // firt submit score: 20, // coding time: 45 // failed when multiple space exists string key, article; getline(cin, key); getline(cin, article); int pos, firstPos = -1; int count = 0; toLower(key); toLower(article); int keySize = key.length(); if (key == article) { cout << 1 << " " << 0; return 0; } while ((pos = article.find(key, pos)) != string::npos) { bool prevSpace = false, nextSpace = false; if (pos == 0) { prevSpace = true; } else { prevSpace = article[pos - 1] == ' ' ? true : false; } if (pos + keySize >= article.size() - 1) { nextSpace = true; } else { nextSpace = article[pos + keySize] == ' ' ? true : false; } if (prevSpace && nextSpace) { count++; if (firstPos < 0) { firstPos = pos; } } pos++; } if (firstPos >= 0) { cout << count << " "; } cout << firstPos; return 0; } ``` 以上代码看起来正确,但是oj上判错,只得20分,目前未找到原因。 --- 这题上面解法时错误的,原因有2: - pos未初始化,可能是一个无法预期的值,造成结果未知。 - 使用find方法,无法精确统计单词,如从"hello world"中,使用find(str, "llo"),也能找到。 正确解法如下: ```c++ /** start time: 8:45 End time: Type: simulator Solution: - - - test case: - - - - first submit score: 100 cause: **/ #include <bits/stdc++.h> using namespace std; void toLowercase(string &s) { transform(s.begin(), s.end(), s.begin(), [](char c) { return isupper(c) ? tolower(c) : c; }); } int main() { // freopen("C:/Users/zengsam/Downloads/P1042_2.in", "r", stdin); string word, text, target = ""; getline(cin, word); getline(cin, text); toLowercase(word); toLowercase(text); int cnt = 0; int firstPos = -1; for (int i = 0; i < text.size(); i++) { if (text[i] == ' ') { if (target == word) { cnt++; if (firstPos < 0) { firstPos = i - target.size(); } } target = ""; } else { target += text[i]; } } if (cnt > 0) { cout << cnt << " " << firstPos; } else { cout << "-1"; } return 0; } ``` 之前我是用istringstream来读取单词,也会无法ac,遇到这类测试用例就无法通过。 "tD" " Td hello abc"。 这类题型还是老老实实一个字符一个字符比较判断。
评论(0)
评论(必填)
名称(必填)
联系方式(可选)
验证码(必填)
提交
评论(必填)
名称(必填)
联系方式(可选)
验证码(必填)