我需要打印单词中出现的所有字母,并重新排列以使出现频率最高的字母位于开头。
单词最多可以包含100,000个字符。
如果字母出现的次数相同,则最小的字母将在按字母顺序排序后首先显示。
某些类和操作在Java中很慢。因此,建议使用BufferedReader和BufferedWriter。
使用字符串的连接速度很慢。
输入:说明
输出:iinnssttcour
public class Main {
public static void main(String[] args) throws IOException {
String line;
BufferedReader reader = new BufferedReader(new
InputStreamReader(System.in));
line = reader.readLine();
StringBuilder sb = new StringBuilder();
Map<Character, Integer> charCountMap = new HashMap<>();
int len = line.length();
for(int i = 0; i < len; i++) {
char ch = line.charAt(i);
charCountMap.put(ch, charCountMap.getOrDefault(ch, 0) + 1);
}
charCountMap.entrySet().stream()
.sorted(Map.Entry.<Character,
Integer>comparingByValue().reversed())
.forEach(record -> {
Character key = record.getKey();
int value = record.getValue();
for(int i = 0; i < value; i++) {
sb.append(key);
}
});
sb.toString();
System.out.println(sb);
}
}
我的第二个解决方案:
public class Main {
public static void main(String[] args) throws IOException {
String inputString;
BufferedReader reader = new BufferedReader(new
InputStreamReader(System.in));
inputString = reader.readLine();
if(reader != null)
reader.close();
int[] letterArray = new int[26];
char[] letters = new char[26];
for(int i=0;i<=25;i++)
letters[i] = (char)(97+i);
for(int i=0; i< inputString.length(); i++)
letterArray[inputString.charAt(i) - 97] +=1 ;
for(int i=0; i<=24;i++)
for(int j=i+1;j<=25;j++){
if(letterArray[i] <letterArray[j] || (letterArray[i] ==
letterArray[j] && letters[i] > letters[j])){
int temp = letterArray[i];
letterArray[i] = letterArray[j];
letterArray[j] = temp;
char temp2;
temp2 = letters[i];
letters[i] = letters[j];
letters[j] = temp2;}
}
String outputString = new String();
for(int i=0;i<=25;i++){
for(int j = 0; j<letterArray[i]; j++)
outputString += letters[i];}
System.out.println(outputString);}
}
Comparator.comparing(...).thenComparing(...)
实现排序的“之后”部分。 valueComparator
按字母频率排序:
Comparator<Entry<Character, Integer>> valueComparator = (e1, e2) ->
e2.getValue().compareTo(e1.getValue()); // reverse order
然后按字母顺序排序keyComparator
:
Comparator<Entry<Character, Integer>> keyComparator = valueComparator
.thenComparing((e1, e2) -> e1.getKey().compareTo(e2.getKey()));
尝试一下:
StringBuilder sb = new StringBuilder();
Map<Character, Integer> charCountMap = new HashMap<>();
for (char c : line.toCharArray()) {
charCountMap.put(c, charCountMap.getOrDefault(c, 0) + 1);
}
Comparator<Entry<Character, Integer>> valueComparator = (e1, e2) -> e2.getValue().compareTo(e1.getValue());
Comparator<Entry<Character, Integer>> keyComparator = valueComparator
.thenComparing((e1, e2) -> e1.getKey().compareTo(e2.getKey()));
charCountMap.entrySet().stream().sorted(keyComparator).forEach(e -> {
int i = 0;
while (i < e.getValue()) {
sb.append(e.getKey());
i++;
}
});
System.out.println(sb.toString());
输出:
iinnssttcoru
public void main(String[] args) throws IOException {
String line;
line = "instructions"; // I've left out the Reader for brevity's sake
StringBuilder sb = new StringBuilder();
Map<Character, Integer> charCountMap = new HashMap<>();
int len = line.length();
for (int i = 0; i < len; i++) {
char ch = line.charAt(i);
charCountMap.put(ch, charCountMap.getOrDefault(ch, 0) + 1);
}
charCountMap.entrySet().stream().sorted((first, second) -> {
if (first.getValue() > second.getValue())
return -1;
if (first.getValue().equals(second.getValue()))
return first.getKey() - second.getKey();
return 1;
}).forEach(record -> {
Character key = record.getKey();
int value = record.getValue();
for (int i = 0; i < value; i++) {
sb.append(key);
}
});
System.out.println(sb.toString());
}
比较器(在此声明为功能接口)首先检查字母的计数。仅当它们相等时,它也会检查到位的字符。