不管是自动化测试,还是测试开发,或者高级测试工程师,国内很多公司都开始要求编码能力。在各种面试中,经常会问到一些编程如何实现的问题。本系列,专门记录一些面试中遇到的问题,主要是用Java来实现,后续如果有精力,会更新Python实现方法。
题目;给出一个字符串,统计出每个字母出现的次数。
思路分析:
需要统计字母和字母出现次数,这个第一反应就想起了编程语言中的字典概念,字母就相当于字典中的key,字母出现次数就是字典的value,而且字典要求key不能重复。这个编程题目打印的结果其实就是一个字典。第二个和key和value有关的概念就是map,和字典差不多。本题有两种解题方法,第一种是普通的数组,第二种就是map。两种方法,我们都需要掌握,先看看数组解法,然后看看map,之后对比,肯定是map的代码更少,效率更高。
在开始采用数组解法之前,我们来通过以下步骤拆分,一步一步达到我们的目的,这样,才能掌握这个知识点。
1.1 限制只有小写字母的情况
数据举例,str=”abcab”
核心实现思想:
1) 创建一个int[] a类型数组,大写26,因为只有26个小写英文字母。例如a[0]表示字母a的出现次数,a[1]表示字母b的出现次数,依次类推….
2) 依次取出每个字母,利用str.charAt(i)函数。Tmp作为临时取出字母。
3) 从char数组(字符串本身就是一个特殊的char类型数组)索引为0开始和 tmp比较,记录索引位置。索引得到的方式是tem-‘a’,我们知道小写字母a对应的ascii码是数字97,大写A对应是数字65,因为都是小写字母,tem-97得到的值最小是0,这个0就存储到统计次数的数组a[0],这个时候,因为执行了tem-97,说明存在一个字母,相对于这个字母出现了一次,那么a[0]=a[0]+1。用str=”abcab”,举例,循环第一次是字母a,这个时候tem=a, 执行tem-97=0,那么统计a出现次数就是a[0]=a[0]+1,这个值等于1。等遍历到第四次位置,出现了第二个a,而且tem-97=0的,那么这个时候a[0]会继续加1,这个时候字母a就出现了两次。
用Java代码实现
package test;
public class CharCount {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 只考虑全部小写
String str1 = "abca";
int[] count = new int[26]; //用来存储小写字母a-z出现的次数。
for(int i=0; i
输出结果:
字母a出现次数:2
字母b出现次数:1
字母c出现次数:1
为了测试一些其他情况,这里我们把str1="efeffhkkhgihwfwefhxfhhfnbbfeyfhkmadgfeifjfc",替换上面str1,运行结果。
字母a出现次数:1
字母b出现次数:2
字母c出现次数:1
字母d出现次数:1
字母e出现次数:5
字母f出现次数:12
字母g出现次数:2
字母h出现次数:7
字母i出现次数:2
字母j出现次数:1
字母k出现次数:3
字母m出现次数:1
字母n出现次数:1
字母w出现次数:2
字母x出现次数:1
字母y出现次数:1
package test;
public class CharCount {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 只考虑全部大写
String str1 = "ABCBAFRIJGHEGJEEFEJDGJLKKOPOPXDNMH";
int[] count = new int[26]; //用来存储字母A-Z出现的次数。
for(int i=0; i
字母A出现次数:2
字母B出现次数:2
字母C出现次数:1
字母D出现次数:2
字母E出现次数:4
字母F出现次数:2
字母G出现次数:3
字母H出现次数:2
字母I出现次数:1
字母J出现次数:4
字母K出现次数:2
字母L出现次数:1
字母M出现次数:1
字母N出现次数:1
字母O出现次数:2
字母P出现次数:2
字母R出现次数:1
字母X出现次数:1
1.3 不限制大小写字母
因为题目,没有限制大小写的字母,甚至输入其他键盘上存在的键盘或者数字。这次,我们依然只关注大写和小
写字母,其他字符不管。核心思路就是,先判断是否是字母,如果是字母,就执行上面的统计方法。
package test;
public class CharCount {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 只考虑全部小写
String str1 = "ABdgeIJkdj";
int[] count = new int[52]; //用来存储字母a-z A-Z出现的次数。
for(int i=0; i=65&& tmp<=90)||(tmp>=97&& tmp<=122)){
int index = tmp - 65; //利用ascii码表,最小结果是0.
count[index] = count[index] + 1;
}
}
//循环打印每个字母出现次数
for(int j=0; j
运行结果
字母A出现次数:1
字母B出现次数:1
字母I出现次数:1
字母J出现次数:1
字母d出现次数:2
字母e出现次数:1
字母g出现次数:1
字母j出现次数:1
字母k出现次数:1
1.4 用map实现
package test;
import java.util.Map;
import java.util.TreeMap;
public class CharCount {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 只考虑全部小写
String str1 = "ADHfggegJKEFdjiwDdgrgrgfGgrgrRd";
//用map实现
TreeMap map = new TreeMap();
for(Character ch: str1.toCharArray()){
//判断是否为字母,其他符号不考虑统计
if( (ch>='a'&& ch<='z')|| (ch>='A'&&ch<='Z') ){
Integer count = map.get(ch);
map.put(ch, null==count?1:count+1);
}
}
//遍历map
for(Map.Entry enter: map.entrySet()){
System.out.println("字母:"+enter.getKey() +"出现次数:"+enter.getValue());
}
}
}
字母:A出现次数:1
字母:D出现次数:2
字母:E出现次数:1
字母:F出现次数:1
字母:G出现次数:1
字母:H出现次数:1
字母:J出现次数:1
字母:K出现次数:1
字母:R出现次数:1
1.5 分别统计英文字母,空格,数字和其他字符出现次数
这里变化一下需求,分别统计英文字母,数字,空格和其他字符统计次数。
package test;
public class CharCount {
public static void main(String[] args) {
String str1 = "df dADF 23ad 8D35A HELLworld #$^&*";
int charCount = 0;
int numberCount = 0;
int blankCount = 0;
int otherCount = 0;
for(int i=0; i='a'&&tmp<='z')||(tmp>='A'&&tmp<='Z')){
charCount++;
}
//主要不要写成tmp>0,这里是ascii码表比较
else if(tmp>='0' && tmp<='9'){
numberCount++;
}
else if(tmp==' '){
blankCount++;
}
else{
otherCount++;
}
}
System.out.println("英文字母出现次数:" +charCount);
System.out.println("数字出现次数:" +numberCount);
System.out.println("空格出现次数:" +blankCount);
System.out.println("其他字符出现次数:" +otherCount);
}
}
英文字母出现次数:19
数字出现次数:5
空格出现次数:5
其他字符出现次数:5
总结:
关于字符统计的编程,掌握了以上方法应该是足够了。这里,你可以试试用Python语言写,或者用shell写,记得之前面试,关于shell这块,有人问要用shell脚本语言实现,没办法,shell语法还不如java语法掌握得好,回答不上来。