409 - Excuses, Excuses!

题意:
找出最差劲的借口. 给出一组 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

你可能感兴趣的:(uva,409,Excuses,Excuses!)