某知名IT公司最近的一道笔试编程题
因为笔试时答应对题目保密,故在此就不说出公司名了。欢迎交流,共同探讨。
一 问题描述
给定任一字符串(可以有中文),长度为任意,要求找出其出现次数最多的字符及计算次数。
二 分析
在JAVA中,所有的字符可以统一用unicode表示。在最坏的情况下(即字符串中所有的字符均不相同),至少需要String.length()个存储单元(用数组存储),下面就是考虑把String中的每一字符映射到array[0]到array[length-1]的数组中。自然想到用Hash Table来实现,Hash函数可以定义为 int position=unicode%c.length 看代码吧,注释很详细。
三 源代码
/**
* @(#)CountChar.java
*
*
* @author LUORUI
* @version 1.00 2007/9/25
*/
class item { //定义哈希表中的元素
public char a;
public int count=0;
public item ( ) {
this.a=' ';
this.count= 0;
}
}
public class CountChar {
public static void getMaxchar(String s){
char[] c=s.toCharArray();
item[] ht=new item[c.length]; //最坏的情况下(每个字符均不一样),需要c.length个存储单元
for(int i=0;i<=c.length-1;i++){ //赋初值,防止出现空指针引用 ********小心******
ht[i]=new item ( ) ;
}
item Maxitem=ht[0];
for(int i=0;i<=c.length-1;i++){
int unicode=(int)c[i]; // 获得字符的unicode值 ()
int position=unicode%c.length; //自定义的Hash函数
if (ht[position].count==0) { //第一次扫描到的字符放入数组中
ht[position].a=c[i];
ht[position].count=1;
}
else
if (ht[position].a==c[i]) //扫描到了同样的字符,count加1
ht[position].count++;
else for (int j= position+1;j!= position-1;position++ ) { //Hash表发生地址冲突,用线形探测法解决地址冲突
if (ht[position].count==0) {
ht[position].a=c[i];
ht[position].count=1; //找到空位置,插入
break; } // 找到,跳出循环
if (position==c.length-1) //往后找,无空位可插入,则往前找
position=0;
}
}
for(int i=1;i<=c.length-1;i++){ //遍历数组,找到一个最大值
if (ht[i].count> Maxitem.count )
Maxitem=ht[i];
}
for(int i=1;i<=c.length-1;i++){ //遍历数组,找到所有的最大值,譬如”31212“这种多个最大值情况
if ( ht[i].count== Maxitem.count )
System.out.println("出现次数最多的字符是:"+ht[i].a+" 次数是:"+ ht[i].count );
}
}
public static void main(String[] args) {
CountChar.getMaxchar("本代码的作者是IT55551985euiollgjIT5riugjkj51ITIT1IT45ITITdjjkklITITdfjIT瑞");
} //供测试用的字符串
}
结果输出 C:/>javac CountChar.java
C:/>java CountChar
出现次数最多的字符是:I 次数是:10
出现次数最多的字符是:T 次数是:10