1. 程式人生 > >55 - 字符流中第一個不反復的字符

55 - 字符流中第一個不反復的字符

rst static -s urn track rtc name string mes

當從字符流中僅僅讀出前兩個字符“go”時,第一個僅僅出現一次的字符是‘g’。當從該字符流中讀出前六個字符“google”時。第一個僅僅出現 1 次的字符是”l”。


首先要記錄一個字符出現的次數,為了實現O(1)查找。使用簡易hash表存儲。用occurences[256] 記錄字符出現的次數。設置:
occurences[i] = 0, 該字符未出現;
occurences[i] = 1, 該字符出現一次;
occurences[i] = 2, 該字符出現2次或大於2次
使用先進先出的隊列記錄。出現一次的字符

在後面的字符輸入過程中,可能會輸入一個已經存在一次的字符,隊列裏可能存在不止出現一次的字符。因此在取隊列頂元素時,應再次檢查該元素是否出現1次,假設不是,則隊列pop。直至找到一個僅僅出現一次的字符索引。

時間復雜度O(1)
空間復雜度:occurences[256] 空間恒定;隊列最多僅僅會存在256個字符(僅僅會push第一次出現的字符)。因此空間復雜度O(1)

#include <iostream>
#include <queue>
using namespace std;
class CharStatics {
private:
    unsigned int occurences[256];
    int index;
    queue<int> index_queue;
public:
    CharStatics() {
        index = -1
; for (int i = 0; i <= 255; i++) occurences[i] = 0; } void InsertChar(char ch) { if (occurences[ch] == 0) { occurences[ch] = 1; // 第一次出現,設置出現次數,壓入隊列 index_queue.push(ch); } else { occurences[ch] = 2;// 第 2 次或多次出現 } } char
FirstApperingOnce() { // 找到最先僅僅出現一次的字符,並用index指向 while (!index_queue.empty() && occurences[index_queue.front()] != 1) { index_queue.pop(); } if (!index_queue.empty()) index = index_queue.front(); else index = -1; // 沒有僅僅出現一次的字符 if (index == -1) return ‘\0‘; return index+‘\0‘; } }; int main() { CharStatics str; str.InsertChar(‘g‘); cout << str.FirstApperingOnce() << endl; str.InsertChar(‘o‘); cout << str.FirstApperingOnce() << endl; str.InsertChar(‘o‘); cout << str.FirstApperingOnce() << endl; str.InsertChar(‘g‘); cout << str.FirstApperingOnce() << endl; str.InsertChar(‘l‘); cout << str.FirstApperingOnce() << endl; str.InsertChar(‘e‘); cout << str.FirstApperingOnce() << endl; }

輸出:

g
g
g
NUL
l
l

55 - 字符流中第一個不反復的字符