版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
40.流中第一个出现一次的字符(247)
-
题目描述:请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
-
输出描述:如果当前字符流没有存在出现一次的字符,返回#字符。
-
思路:要解决的问题是:字符出现的次数以及字符出现的次序。
字符出现的次数:可以用一个哈希表来存储字符出现的次数,字符的 ‘哈希值’ 就为数组的下标。
字符出现的次序:
对于数组中存放的次数可以这样来设计:
(1)首先将数组的值初始化为-1,表示下标所对应的字符还没有出现过。
(2)当字符第一次出现时,将该字符所对应的数组的值改为 该字符所出现的位置。
次序:可以用一个类变量来存储次序,每加进一个字符就加1 。
(3)当字符所对应的数组的值不为-1(>=0),表示该字符已经出现过,值计为-2。
(4)我们关心的是第一次出现的字符,所以对于只出现一次的字符所对应的数组值为该字符出现在原字符流中的位置(0,1,4…),没有出现过的字符的数组值为-1,出现过多次的字符的数组值为-2。这样我们在查找第一个出现一次的字符的时候,可以查找数组中 大于0的数,并且要找到一个大于0的数中最小的一个数,这样才是第一次出现一次的字符。(大于0的数为只出现过一次的字符,大于0的数中最小的数为第一次只出现一次的字符)
扫描二维码关注公众号,回复: 7194868 查看本文章
package _40.流中第一个出现一次的字符;
import java.util.Arrays;
/**
* 一个字符一个字节,8位,所以一共有2^8=256个字符
* @author Administrator
*
*/
public class FirstAppearingOnce {
//-1:表示没有出现过;>0:表示出现过一次(大于0中最小的数为第一次出现的字符);-2表示出现过多次
int[] times;//哈希表:数组的下标为字符的ASCII
int index;//记录字符流中每个字符出现的位置
// 将times的数值初始化为-1;
public FirstAppearingOnce() {
times = new int[256];
index = 0;
for(int i = 0; i < times.length; i++){
times[i] = -1;
}
}
public void insert(char ch) {
//如果字符第一次出现,将值置为该字符出现在原字符流中的位置
if(times[ch] == -1){
times[ch] = index;
}
else{
times[ch] = -2;
}
index++;
}
public char find() {
int minIndex = 256;
char rst = '#';
for(int i = 0; i < times.length; i++){
if(times[i] >=0 && times[i] < minIndex){
rst = (char)i;
minIndex = times[i];
}
}
return rst;
}
public static void main(String[] args) {
String str = "google";
FirstAppearingOnce charStatistics = new FirstAppearingOnce();
for(int i=0;i<str.length();i++){
charStatistics.insert(str.charAt(i));
System.out.print(charStatistics.find());
}
}
}