题意:
找出最差劲的借口. 给出一组 keywords 和一组 excuses, 找出包含最多 keywords 的 excuse 并输出.
思路:
对于输入的每一个 excuse, 都计算其包含的 keyword 数:
(1). 若 keyword 数 > maxIncidence, 则清空 worst 数组, 把这个 excuse 添加到 worst 中;
(2). 若 keyword 数 = maxIncidence, 只把 这个 excuse 添加到 worst 中即可;
(3). 若 keyword 数 < maxIncidence, 则不进行操作.
要点:
1. keywords 都是小写, excuse 是包含大小写的, 所以需要把读进来的 excuse 先转成小写再进行比较(最后输出结果必须是原来包含大小写的 excuse).
2. 这里的包含 keyword 要求"全词匹配", 即 keyword 如果是 excuse 中某一个词的一部分, 是不能计算在内的.
3. vector.clear() 不会释放空间, 要释放空间需要 vector<T>().swap(x).
4. 使用 copy(worst.begin(), worst.end(), ostream_iterator<string>(cout, "\n")); 直接输出 vector 中的数据, 每输出一个都以 "\n" 分隔.
5. ostream_iterator 需要添加 <iterator> 头文件,否则会报 error: 'ostream_iterator' was not declared in this scope.
6. 以下代码中的 lowerExcuse 不能默认为空, 因为 transform 不会分配空间, 即写成 string lowerExcuse;是不对的;
string lowerExcuse = excuses[i]; transform(excuses[i].begin(), excuses[i].end(), lowerExcuse.begin(), ::tolower);
题目:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=96&page=show_problem&problem=350
代码:
# include <iostream> # include <string> # include <cstdio> # include <cstring> # include <vector> # include <algorithm> # include <iterator> // ostream_iterator<> # include <cctype> using namespace std; // 获取 keywords 在 excuse 中出现的次数 int getIncidence(const string& excuse, const vector<string>& keywords) { int cnt = 0; for(int i=0; i<keywords.size(); i++){ size_t found = -1; // 这里下一个查找要是从 found+1 开始, 不然会死循环 while( (found = excuse.find(keywords[i], found+1)) != string::npos ){ // 只在这个 keyword 是完全匹配的情况才计一次数, 即除了首末单词, 其他情况下, keyword 匹配的地方必须不能有字母包含 if( 0 == found || excuse.length() == (found + keywords[i].size()) ){ cnt++; }else{ size_t left = found - 1; size_t right = found + keywords[i].size(); if((!isalpha(excuse[left])) && (!isalpha(excuse[right]))){ cnt++; } } } } return cnt; } int main(int argc, char const *argv[]) { #ifndef ONLINE_JUDGE freopen ("409_i.txt", "r", stdin); freopen ("409_o.txt", "w", stdout); #endif int caseNum = 0; while(!cin.eof()){ int K; int E; cin >> K >> E; cin.ignore(); vector<string> keywords; vector<string> excuses; // 读入 keywords for(int i=0; i<K; i++){ string keyword; getline(cin, keyword); keywords.push_back(keyword); } // 读入 excuse for(int i=0; i<E; i++){ string excuse; getline(cin, excuse); excuses.push_back(excuse); } vector<string> worst; int maxIncidence = 0; for(int i=0; i<excuses.size(); i++){ // 全部转成小写 string lowerExcuse = excuses[i]; // 这里 lowerExcuse 不能默认为空, 因为 transform 不会分配空间 transform(excuses[i].begin(), excuses[i].end(), lowerExcuse.begin(), ::tolower); // 获取 keywords 出现次数 int incidence = getIncidence(lowerExcuse, keywords); if(incidence > maxIncidence){ worst.clear(); // 这个不会释放空间, 要释放空间需要 vector<T>().swap(x); worst.push_back(excuses[i]); maxIncidence = incidence; }else if(incidence == maxIncidence){ worst.push_back(excuses[i]); } } cout << "Excuse Set #" << ++caseNum << endl; copy(worst.begin(), worst.end(), ostream_iterator<string>(cout, "\n")); // 输出 worst cout << endl; } return 0; }
环境: C++ 4.5.3 - GNU C++ Compiler with options: -lm -lcrypt -O2 -pipe -DONLINE_JUDGE