题目:字符流中第一个不重复的字符
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中读出前两个字符“go”时,第一个只出现一次的字符是“g”.当从该字符流中读出前六个字符“google”时,第一个只出现一次的字符是"l".
算法分析:
字符只能一个接着一个从字符流中读出来。可以定义一个数据容器来保存字符在字符流中的位置。当一个字符第一次从字符流中读出来时,把它在字符流中的位置保存到数据容器里。当这个字符再次从字符流中被读出来时,那么它就不是只出现一次的字符,也就可以被忽略了。这时把它在数据容器里保存的值更新成一个特殊的值(比如负值)。
为了尽可能高校地解决这个问题,需要在O(1)时间内往容器里插入一个字符,以及更新一个字符对应的值。这个容器可以用哈希表来实现。用字符的ASCII码作为哈希表的键值,而把字符对应的位置作为哈希表的值。
算法实现源程序:
/**************************************************************
* Copyright (c) 2016,
* All rights reserved.
* 版 本 号:v1.0
* 题目描述:字符流中第一个不重复的字符
* 请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中读出前两个字符“go”时,
* 第一个只出现一次的字符是“g”.当从该字符流中读出前六个字符“google”时,第一个只出现一次的字符是"l".
* 输入描述: 请输入一个要判断的字符串:
* -12E-16
* 程序输出:算法1的判断的结果是:true
* 算法2的判断结果是:true
* 问题分析: 1.整个字符串不需要从头循环到尾,只需要一次次向后移动所指向的字符即可
* 算法描述:字符只能一个接着一个从字符流中读出来。可以定义一个数据容器来保存字符在字符流中的位置。
* 当一个字符第一次从字符流中读出来时,把它在字符流中的位置保存到数据容器里。当这个字符再次从字符流中被读出来时,
* 那么它就不是只出现一次的字符,也就可以被忽略了。这时把它在数据容器里保存的值更新成一个特殊的值(比如负值)。
* 为了尽可能高校地解决这个问题,需要在O(1)时间内往容器里插入一个字符,以及更新一个字符对应的值。
* 这个容器可以用哈希表来实现。用字符的ASCII码作为哈希表的键值,而把字符对应的位置作为哈希表的值。
* 完成日期:2016-10-12
***************************************************************/
package org.marsguo.offerproject55;
import java.util.ArrayList;
import java.util.HashMap;
class SolutionMethod1{
int[] hashtable = new int[256];
StringBuffer s= new StringBuffer();
public void Insert(char ch){
s.append(ch);
if(hashtable[ch] == 0)
hashtable[ch] = 1;
else hashtable[ch]+= 1;
}
public char FirstAppearingOnce(){
char[] str = s.toString().toCharArray();
for(char c:str){
if(hashtable[c] == 1)
return c;
}
return '#';
}
}
class SolutionMethod2{
HashMap<Character,Integer> map = new HashMap();
ArrayList<Character> list = new ArrayList<Character>();
public void Insert(char ch){
if(map.containsKey(ch)){
map.put(ch, map.get(ch)+1);
}
else{
map.put(ch, 1);
}
list.add(ch);
}
public char FirstAppearingOnce(){
char c = '#';
for(char key :list){
if(map.get(key) == 1){
c = key;
break;
}
}
return c;
}
}
public class CharStatistics {
public static void main(String[] args){
}
}