请编写代码,统计字符串中英文字母、空格、数字和其他字符的个数。
在本题的 Solution
类中有个 getLettersCounts()
方法,该方法有一个 String
类型的参数 s
,s
代表传入的字符串。该方法要统计传入字符串中所有的英文字母、空格、数字和其他字符的个数,然后将他们的统计结果依次添加到 Map<String, Integer>
集合中,最后返回这个集合。返回值为 Map<String, Integer>
类型,其中,Map
集合的键为字符的类型(即英文字母 Letters
、数字 Numbers
、空格 Spaces
和其他字符 Others
)。
getLettersCounters()
方法中已经定义了四个 int
类型的变量 letters
、nums
、spaces
和 ohters
,它们的初始值都为 0
,分别表示英文字母的个数、数字的个数、空格的个数和其他字符的个数。
1.你不需要对输出的顺序进行任何操作,只需要在 Map
中按照题目给定的键值对进行存储,并将其返回即可。
2.Map
的键为 Letters
、Numbers
、Others
和 Spaces
,值为键代表的字符对应的数量。
由于 getLettersCounts()
方法返回的是一个 Map
集合,所以无需对输出进行格式化。
样例一
输入:
a1 b2 c3 d4;
输出:
{Numbers=4, Others=1, Letters=4, Spaces=3}
样例二
输入:
JDK 8 is very popular ~
输出:
{Numbers=1, Others=3, Letters=16, Spaces=5}
解题思路
本题要求我们统计输入的字符串中每个字符的个数,我们可以通过将输入的字符串先转换为字符数组,再通过遍历来判断每一个字符以完成个数的统计。
字符串转字符数组可以使用 String
类的 toCharArray()
方法来实现:
char[] chars = ();
对于字符类型的判断,我们可以使用传统的单引号加字符的方式(如 'a'
)进行判断,也可以使用 ASCII 码的方式来判断,这里以 ASCII 码判断法为例:
for (char c : arr) {
if (c >= 48 && c <= 57) {
// 字符c为数字
nums++;
} else if (c >= 65 && c <= 90 || (c >= 97 && c <= 122)) {
// 字符c为字母 65~99为大写字母 97~122为小写字母
letters++;
} else if (c == 32) {
// 字符c为空格
spaces++;
} else {
others++;
}
}
由于 getLettersCounts()
方法的返回类型为 Map<String, Integer>
,同时,使用 Map
来实现键值对的存储也能够提高代码的性能。这里的键(Key)就是字符类型,值(Value)就是字符类型对应的数量:
Map<String, Integer> map = new HashMap<>();
("Numbers", nums);
("Letters", letters);
("Spaces", spaces);
("Others", others);
存储值的方式也可以直接在遍历字符数组中使用:
for (char c : arr) {
if (c >= 48 && c <= 57) {
// 字符c为数字
("Numbers", ++nums);
} else if (c >= 65 && c <= 90 || (c >= 97 && c <= 122)) {
// 字符c为字母 65~99为大写字母 97~122为小写字母
("Letters", ++letters);
} else if (c == 32) {
// 字符c为空格
("Spaces", ++spaces);
} else {
("Others", ++others);
}
}
但需要注意的是,通过这种方式也会有一个易错点,即存储键值对的时候,值的自增应该是 ++value
而不是 value++
,前者是先自增值后存储,而后者是先存储后自增,这会导致输出的值比实际少 1。
题解代码
import ;
import ;
import ;
public class Main {
public static void main(String[] args) {
try {
String inputPath = args[0];
String outputPath = args[1];
Scanner sc = new Scanner(new FileReader(inputPath));
PrintStream ps = new PrintStream(outputPath);
// 获取输入的字符串
String s = ();
Solution solution = new Solution();
// 调用方法并输出结果
((s));
();
} catch (Exception e) {
();
}
}
}
import .*;
public class Solution {
public Map<String, Integer> getLettersCounts(String s) {
int nums = 0;//数字
int letters = 0;//字母
int spaces = 0;//空格
int others = 0;//其他
Map<String,Integer> map = new HashMap<>();
char[] chars = ();
for(char c : chars){
if(c >= 48 && c <= 57){
// 字符c为数字
("Numbers",++nums);
}else if (c == 32){
// 字符c为空格
("Spaces",++spaces);
}else if(c >= 65 && c <= 90 || c >=97 && c <= 122){
// 字符c为字母 65~99为大写字母 97~122为小写字母
("Letters",++letters);
}else{
("Others",++others);
}
}
return map;
}
}
知识要点
1. char类型与ASCII码
-
char
类型:用于描述一个代码单元。对于基本的多语言平面中的字符(码点范围U+0000
到U+FFFF
,不包含替换区域)可以使用一个代码单元表示,也就是一个char
值。对于其他平面的字符(码点范围U+10000
到U+10FFFF
)可以使用两个代码单元表示,也就是两个char
值。严格来说,char
类型可以表示使用一个代码单元表示的Unicode
字符,char
类型无法直接表示两个代码单元表示的字符。 - ASCII 码:是
American Standard Code for Information Interchange
的缩写,而不是 ASCⅡ(罗马数字 2),有很多人在这个地方产生误解。ASCII 码也是现今最通用的单字节编码系统。