本文參考自《劍指offer》一書,代碼採用Java語言。html
更多:《劍指Offer》Java實現合集 java
請實現一個函數用來找出字符流中第一個只出現一次的字符。例如,當從字符流中只讀出前兩個字符"go"時,第一個只出現一次的字符是'g'。當從該字符流中讀出前六個字符"google"時,第一個只出現一次的字符是'l'。函數
字符只能一個一個從字符流中讀出來,所以要定義一個容器來保存字符以及其在字符流中的位置。post
爲儘量搞笑解決問題,要在O(1)時間內往數據容器中插入字符,及其對應的位置,所以這個數據容器能夠用哈希表來實現,以字符的ASCII碼做爲哈希表的鍵值key,字符對應的位置做爲哈希表的值value。測試
開始時,哈希表的值都初始化爲-1,當讀取到某個字符時,將位置存入value中,若是以前讀取過該字符(即value>=0),將value賦值爲-2,表明重複出現過。最後對哈希表遍歷,在value>=0的鍵值對中找到最小的value,該value即爲第一個只出現一次的字符,ASCII碼爲key的字符即爲所求字符。google
測試算例 url
1.功能測試(讀入一個字符;讀入多個字符;全部字符都惟一;全部字符重複)操作系統
2.特殊測試(讀入0個字符)code
//題目:請實現一個函數用來找出字符流中第一個只出現一次的字符。例如,當從 //字符流中只讀出前兩個字符"go"時,第一個只出現一次的字符是'g'。當從該字 //符流中讀出前六個字符"google"時,第一個只出現一次的字符是'l'。 public class FirstCharacterInStream { private int index; private int[] occurence; public FirstCharacterInStream() { //在構造函數中初始化成員變量 index=0; occurence = new int[256]; for(int i=0;i<256;i++) { occurence[i]=-1; } } public void insert(char ch) { if(occurence[(int)ch]==-1) { occurence[(int)ch]=index; //第一次出現 }else if(occurence[(int)ch]>=0) { occurence[(int)ch]=-2; //已經出現過了 } index++; } public char getFirst() { int minIndex=Integer.MAX_VALUE; //最大的integer char ch='#'; for(int i=0;i<256;i++) { if(occurence[i]>=0 && occurence[i]<minIndex) { ch = (char) i; minIndex=occurence[i]; } } return ch; } }
1.對於數據流、字符流等,須要定義數據容器來保存記錄。htm
流和串的區別:
1)串:字符串已經保存下來了,可以讀取遍歷,所以在字符串中第一個只出現一次的字符中,只須要存下每一個字符出現的個數,而後直接在字符串中遍歷;
2)流:字符流沒有存下來,沒法進行遍歷,所以在本題中,只能在數據容器哈希表中遍歷,並且哈希表中存放的是對應字符的位置,而不是個數。
2.記得會用構造函數來初始化參數;
3.Integer.MAX_VALUE=2^31-1,是32位操做系統(4字節)中最大的符號型整型常量。
4.分清楚:字符與ASCII碼的轉化,以及 字符形式的數字轉和整型數字間的轉化
public static void main(String[] args) { //字符轉化爲ASCII碼 char ch_a = 'a'; int code_a = (int)ch_a; // =ASCII碼97 //ASCII碼轉化爲字符 char copyCh_a = (char) code_a; // =ASCII碼97對應的字符'a' //字符形式數字轉化爲整型 char c1 = '2'; int n1 = c1-'0'; //=2, 由'2'和'1'的ASCII碼相減獲得 //數字轉化爲字符形式 char copyC1 = (char)(n1+'0'); //='2' ,由'0'的ASCII碼加2獲得'2'的ASCII碼 System.out.println(5); }