题目描述
小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组 成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得最多来分辨单词。
现在,请你帮助小蓝,给了一个单词后,帮助他找到出现最多的字母和这 个字母出现的次数。
输入描述
输入一行包含一个单词,单词只由小写英文字母组成。
对于所有的评测用例,输入的单词长度不超过 1000。
输出描述
输出两行,第一行包含一个英文字母,表示单词中出现得最多的字母是哪 个。如果有多个字母出现的次数相等,输出字典序最小的那个。
第二行包含一个整数,表示出现得最多的那个字母在单词中出现的次数。
样例">输入输出样例
示例 1
输入:lanqiao
输出:
a
2
示例2
输入:longlonglongistoolong
输出:
o
6
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
解题思路:
首先,按照惯例,先使用最简单的方法实现该问题的求解,即对字符串进行遍历,对每一个字符进行判断并计算二十六个英文字母中每一个字符出现的次数,并对次数进行判断得到字典序列最小并且出现次数最多的那单词并进行输出,Java实现如下(代码非常长):
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String words = scan.next();
int timeA = 0, timeB = 0, timeC = 0, timeD = 0, timeE = 0, timeF = 0, timeG = 0, timeH = 0,
timeI = 0,timeJ = 0,timeK = 0,timeL = 0,timeM = 0, timeN = 0, timeO = 0, timeP = 0,
timeQ = 0, timeR = 0, timeS = 0, timeT = 0, timeU = 0, timeV = 0, timeW = 0, timeX = 0,
timeY = 0, timeZ = 0;
int len = words.length();
for (int i = 0; i < len; i++) {
char c = words.charAt(i);
if (c == 'a'){
timeA++;
}else if (c == 'b'){
timeB++;
}else if (c == 'c'){
timeC++;
}else if (c == 'd'){
timeD++;
}else if (c == 'e'){
timeE++;
}else if (c == 'f'){
timeF++;
}else if (c == 'g'){
timeG++;
}else if (c == 'h'){
timeH++;
}else if (c == 'i'){
timeI++;
}else if (c == 'j'){
timeJ++;
}else if (c == 'k'){
timeK++;
}else if (c == 'l'){
timeL++;
}else if (c == 'm'){
timeM++;
}else if (c == 'n'){
timeN++;
}else if (c == 'o'){
timeO++;
}else if (c == 'p'){
timeP++;
}else if (c == 'q'){
timeQ++;
}else if (c == 'r'){
timeR++;
}else if (c == 's'){
timeS++;
}else if (c == 't'){
timeT++;
}else if (c == 'u'){
timeU++;
}else if (c == 'v'){
timeV++;
}else if (c == 'w'){
timeW++;
}else if (c == 'x'){
timeX++;
}else if (c == 'y'){
timeY++;
}else {
timeZ++;
}
}
List<Integer> arr = new ArrayList<>();
arr.add(0,timeA);
arr.add(1,timeB);
arr.add(2,timeC);
arr.add(3,timeD);
arr.add(4,timeE);
arr.add(5,timeF);
arr.add(6,timeG);
arr.add(7,timeH);
arr.add(8,timeI);
arr.add(9,timeJ);
arr.add(10,timeK);
arr.add(11,timeL);
arr.add(12,timeM);
arr.add(13,timeN);
arr.add(14,timeO);
arr.add(15,timeP);
arr.add(16,timeQ);
arr.add(17,timeR);
arr.add(18,timeS);
arr.add(19,timeT);
arr.add(20,timeU);
arr.add(21,timeV);
arr.add(22,timeW);
arr.add(23,timeX);
arr.add(24,timeY);
arr.add(25,timeZ);
int maxVal = timeA, index = 0, node = 0;
for (Integer num : arr) {
if (num > maxVal){
node = index;
maxVal = num;
}
index++;
}
int key = 97;
for (int i = 1; i <= node; i++) {
key++;
}
char zimu = (char) key;
System.out.println(zimu);
System.out.print(maxVal);
scan.close();
}
}
接下来对该算法进行分析,看到该算法中有很长的代码是死脑筋对每一个字符进行处理并单独记录,使得该算法代码看起来十分繁杂,故对该代码进行简化并提高运行速率。首先类似这种记录次数的题目都可以想到哈希表进行解答,定义一个哈希表,对该输入字符串进行遍历,若该单词出现一次则在对应哈希表的位置将值加一,并通过比较最大值和当前字符对应哈希表出现次数的值进行更新最大值,同时注意考虑到若当前字符对应出现频率等于最大值,则比较字典序。该算法的Java实现如下:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String words = scanner.next();
int[] arr = new int[200];
int len = words.length(), max = 0;
char word = 'a';
for (int i = 0; i < len; i++) {
arr[words.charAt(i)]++;
if (max < arr[words.charAt(i)]){
word = words.charAt(i);
max = arr[words.charAt(i)];
}else if (max == arr[words.charAt(i)]){
if (word > words.charAt(i)){
word = words.charAt(i);
}
}
}
System.out.println(word);
System.out.print(max);
scanner.close();
}
}