55 - 字符流中第一個不反復的字符
阿新 • • 發佈:2017-07-25
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 - 字符流中第一個不反復的字符