题目描述
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
输出描述:
如果当前字符流没有存在出现一次的字符,返回#字符。
思路(哈希表)
一.STL中map实现哈希表
哈希表键值对为 字符:出现次数
1.每读取一个字符便保存至字符串中,同时哈希表字符对应字符+1
2.遍历保存的字符串的每个字符,找到某字符对应的哈希表出现次数=1的对应字符即为所求
二.数组实现哈希表
设定一个容量为256的数组存放每个字符在字符流中出现的状态:
(1)各位均初始化为-1,字符未在字符流中出现过
(2)当某字符第一次出现时,对应位occurrence[i]更新为其在字符流中出现的位置index
(3)当某字符再次出现时,对应位occurrence[i]更新为-2
最后遍历occurrence数组,找到数组中元素值(元素值即为某字符最后出现状态)为>=0,且最小的那个元素对应的字符即为所求字符
注:
1.Solution():index(0){ …} 为有参构造函数(将index初始化为0,并在函数体初始化occurrence数字)
2.初始化minIndex为最大的int型数(针对aaaaaaaaaaaaaa…aaaab),第一个未重复出现在最后,它最大的位置索引也只能为最大的int型数(INT_MAX 或 numeric_limits::max() )
参考链接:
numeric_limits::max()函数
INT_MAX 和 INT_MIN
代码1(STL容器map实现哈希表)
//STL容器实现
class Solution
{
public:
//Insert one char from stringstream
void Insert(char ch)
{
//保存新读取的字符至字符串
s += ch;
//该字符出现次数+1
hashTable[ch]++;
}
//return the first appearence once char in current stringstream
char FirstAppearingOnce()
{
char resultChar = '#';
int sLength = s.size();
for(int i = 0 ; i < sLength ; ++i)
{
if(hashTable[s[i]] == 1)
{
resultChar = s[i];
break;
}
}
return resultChar;
}
private:
map<char, int> hashTable; //声明map实现哈希表,存放对应字符出现的个数( 字符:出现次数)
string s; //用字符串保存读取的字符流
};
代码2(数组实现简单的哈希表)
class Solution
{
public:
//初始化index和occurrence数组
Solution():index(0)
{
for(int i = 0; i < 256; ++i)
occurrence[i] = -1;
}
//Insert one char from stringstream
void Insert(char ch)
{
//某字符未出现过
if(occurrence[ch] == -1)
occurrence[ch] = index;
//某字符出现过一次
else if(occurrence[ch] >= 0)
occurrence[ch] = -2;
//某字符出现过多次,则不处理,字符流位置游标后移一位
++index;
}
//return the first appearence once char in current stringstream
//遍历字符状态数组,寻找元素值最小的且>=0的元素对应的字符即为所求
char FirstAppearingOnce()
{
char resultChar = '#';
int minIndex = numeric_limits<int>::max();
//遍历字符状态数组
for(int i = 0; i < 256 ; ++i)
{
//如果找到仅出现一次的数组,且出现位置最靠前的
if(occurrence[i] >= 0 && occurrence[i] < minIndex)
//更新对应的字符char 和 最小出现位置minIndex
{
resultChar = (char)i; //位置索引强制转换为对应char型字符
minIndex = occurrence[i];
}
}
return resultChar;
}
private:
int index; //字符流位置游标:用于索引某字符出现的位置
int occurrence[256]; //保存各个字符最后状态的数组
};