【ACM】PAT. A1071 Speech Patterns 【STL】

| 题目链接
| 题目分析
| 解题思路

两种思路:
1、 直接用getline(cin, str) 输入一整行,存入string,
清理字符串:特殊字符有可能存在与两个单词的中间,全部用空格代换

注意: 用空格切分得到单词,不要真的用string.erase()切去,只用移动string的下标即可,否则会超时!

2、 用while(cin >> str) 直接按空格划分依次输入"单词",并处理;


【思路一】AC程序(C++)
/**********************************
*@ID: 3stone
*@ACM: PAT.A1071 Speech Patterns
*@Time: 19/2/13
*@IDE: VScode 2018 + clang++ 
***********************************/
#include<cstdio>
#include<string>
#include<iostream>
#include<map>

using namespace std;

string str; //保存字符串
map<string, int> list; //统计单词

//清理字符串
void clearString(int len) {
	for(int i = 0; i < len; i++) {
		if('A' <= str[i] && str[i] <= 'Z') { //转为小写
			str[i] = str[i] - 'A' + 'a';
		} else if( ('0' <= str[i] && str[i] <= '9') || ('a' <= str[i] && str[i] <= 'z') ) {
			continue;
		} else {
			str[i] = ' '; //除数字和字母外用空格替换
		}
	}
} //clearString

//按空格切分字符串
void countWord() {
	string blank = " ";
	int cur = 0;
	while(cur < str.size()) {
		while(str[cur] == ' ') cur++; //擦去前导的空格

		int pos = str.find(blank, cur); //找到下一个空格分界点
	
		string newWord;
		if(pos == string::npos) //若已扫描到str末尾
			newWord = str.substr(cur, str.size() - cur); //最后一个word
		else
			newWord = str.substr(cur, pos - cur); //截取字符
		cur = pos + 1;

		if(list.find(newWord) == list.end()) { //统计出现次数
			list[newWord] = 1; //首次出现
		} else {
			list[newWord]++; //之前已出现过
		}
		if(pos == string::npos) break;
	}
}//countWord


int main() {

	getline(cin, str); //按一行字符串输入
	
	int len = str.size();
	clearString(len); //整理字符串
	
	//切分字符并统计数量
	countWord();

	int maxNum = 0;
	string tarWord; //统计出现最多的字符
	for(map<string, int>::iterator it = list.begin(); it != list.end(); it++) {
		if(maxNum < it->second) {
			maxNum = it->second;
			tarWord = it->first;
		}
	}
	printf("%s %d\n", tarWord.c_str(), maxNum);

	system("pause");
	return 0;
}


【思路二】AC程序(C++)
	/**************************
	//@Author: 3stone
	//@ACM: PAT-A1071 Speech Patterns
	//@Time: 2018/1/25
	//@IDE: VS2017
	***************************/
	#include<cstdio>
	#include<iostream>
	#include<algorithm>
	#include<string>
	#include<set>
	#include<map>

	using namespace std;

	//清理单词
	void clean(string str, set<string> &cleanWord) {
		string tempStr = "";
		for (int i = 0; i < str.size(); ) {
			if (('0' <= str[i] && str[i] <= '9') || ('a' <= str[i] && str[i] <= 'z'))
				i++;
			else if ('A' <= str[i] && str[i] <= 'Z') { //大写 转 小写
				str[i] = 'a' + (str[i] - 'A');
				i++;
			}
			else { //扫描到非法字符
			 //要考虑到 非法字符 可能在 合法字符中间,直接删去就会把两个单词合并了
			 //所以要直接 截取已扫描的所有合法字符
				tempStr = str.substr(0, i);
				if(tempStr != "") cleanWord.insert(tempStr);
				
				str.erase(0, i + 1);  //删去已扫描的所有字符
				i = 0;
			}
		}
		if(str != "") cleanWord.insert(str);
	}

	int main() {
		map<string, int> words; //map会按键值递增排序
		string str;
		set<string> cleanWord;

		while (cin >> str) {
			cleanWord.clear(); //清空
			//一个串可能包含多个合法串,用set保存
			clean(str,cleanWord);//删去无用字符 & 转为小写字母
			
			for (set<string>::iterator it = cleanWord.begin(); it != cleanWord.end(); it++) {
				if (words.find(*it) != words.end()) //是否已有记录
					words[*it]++;
				else
					words[*it] = 1;
			}
		}

		int maxNum = 0;
		string maxOne = ""; //找最大值
		for (map<string, int>::iterator it = words.begin(); it != words.end(); it++) {
			if (it->second > maxNum) {
				maxNum = it->second;
				maxOne = it->first;
			}
		}
		cout << maxOne << " " << maxNum << endl;
		system("pause");
		return 0;
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值