题目描述
- 请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是'g'。当从该字符流中读出前六个字符"google"时,第一个只出现一次的字符是'l'。如果当前字符流没有存在出现一次的字符,返回#字符。
算法分析
- 建立一个256个大小的int型数组来代表哈希表,存储字母出现的位置,-1代表未出现,-2代表已经重复出现,>=0代表字母出现的位置。要找第一个只出现一次的字符,就遍历哈希表,找到表中最小值对应的字母,即为所求。
提交代码:
class Solution {
public:
Solution() : index(0), position(256, -1) {}
void Insert(char ch)
{
if (position[ch] == -1)
position[ch] = index;
else if (position[ch] >= 0)
position[ch] = -2;
++index;
}
char FirstAppearingOnce() {
/* 编译器int类型的最大值 */
int minIndex = numeric_limits<int>::max();
char result = '\0';
for (int i = 0; i < 256; ++i)
{
if (position[i] >= 0 && position[i] < minIndex)
{
result = (char)i;
minIndex = position[i];
}
}
return result;
}
private:
/* 存储每个字符的位置 */
// -1未出现,-2重复出现,>=0位置
vector<int> position;
/* 下一个字符插入位置的索引 */
int index;
};
测试代码:
// ====================测试代码====================
void Test(const char* testName, Solution chars, char expected)
{
if (testName != nullptr)
printf("%s begins: ", testName);
if (chars.FirstAppearingOnce() == expected)
printf("Passed.\n");
else
printf("FAILED.\n");
}
int main(int argc, char* argv[])
{
Solution chars;
Test("Test1", chars, '\0');
chars.Insert('g');
Test("Test2", chars, 'g');
chars.Insert('o');
Test("Test3", chars, 'g');
chars.Insert('o');
Test("Test4", chars, 'g');
chars.Insert('g');
Test("Test5", chars, '\0');
chars.Insert('l');
Test("Test6", chars, 'l');
chars.Insert('e');
Test("Test7", chars, 'l');
return 0;
}