zoukankan      html  css  js  c++  java
  • 《剑指offer》第五十题II:字符流中第一个只出现一次的字符

    // 面试题50(二):字符流中第一个只出现一次的字符
    // 题目:请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从
    // 字符流中只读出前两个字符"go"时,第一个只出现一次的字符是'g'。当从该字
    // 符流中读出前六个字符"google"时,第一个只出现一次的字符是'l'。
    
    #include <cstdio>
    #include <vector>
    #include <limits>
    
    using namespace std;
    
    class CharStatistics
    {
    public:
        CharStatistics() : index(0)  //index=0时初始化hash表, 有点像构造函数
        {
            for (int i = 0; i < 256; ++i)
                occurrence[i] = -1;
        }
    
        void Insert(char ch)  //插入当前字符的位置到hash表中
        {
            if (occurrence[ch] == -1)  //未出现过
                occurrence[ch] = index;
            else if (occurrence[ch] >= 0)  //出现次数1次以上
                occurrence[ch] = -2;
    
            ++index;
        }
    
        char FirstAppearingOnce()
        {
            char ch = '';
            int minIndex = numeric_limits<int>::max();  //类型int的最大值 
    
            for (int i = 0; i < 256; ++i)
            {
                //出现一次且位置最靠前的字符
                if (occurrence[i] >= 0 && occurrence[i] < minIndex)
                {
                    ch = (char)i;  //转换为字符
    
                    minIndex = occurrence[i];  //更新最小位置
                }
            }
            return ch;
        }
    
    private:
        // occurrence[i]: A character with ASCII value i;
        // occurrence[i] = -1: The character has not found;
        // occurrence[i] = -2: The character has been found for mutlple times
        // occurrence[i] >= 0: The character has been found only once
        int occurrence[256];  //hash表
        int index;  //当前字符流的位数
    };
    // ====================测试代码====================
    void Test(const char* testName, CharStatistics chars, char expected)
    {
        if (testName != nullptr)
            printf("%s begins: ", testName);
    
        if (chars.FirstAppearingOnce() == expected)
            printf("Passed.
    ");
        else
            printf("FAILED.
    ");
    }
    
    int main(int argc, char* argv[])
    {
        CharStatistics chars;
    
        Test("Test1", chars, '');
    
        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, '');
    
        chars.Insert('l');
        Test("Test6", chars, 'l');
    
        chars.Insert('e');
        Test("Test7", chars, 'l');
    
        return 0;
    }
    测试代码

    分析:哈希表在需要多次遍历字符串时真好用。

    class Solution
    {
    public:
        
        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
        char FirstAppearingOnce()
        {
            char ch = '#';
            int minIndex = numeric_limits<int>::max();
            
            for (int i = 0; i < 256; ++i)
            {
                if (occurrence[i] >= 0 && occurrence[i] < minIndex)
                {
                    ch = (char)i;
                    minIndex = occurrence[i];
                }
            }
            return ch;
        }
     private:
        int occurrence[256];
        int index;
        
    };
    牛客网提交代码
  • 相关阅读:
    107.JsonResponse
    106.HttpResponse对象详解
    前端学习笔记系列一:2 Vue的单文件组件
    前端学习笔记系列一:1.export default / export const
    @vue-cli的安装及vue项目创建
    Github版本控制系统
    C# 篇基础知识11——泛型和集合
    C# 篇基础知识10——多线程
    C# 篇基础知识9——特性、程序集和反射
    C# 篇基础知识8——正则表达式
  • 原文地址:https://www.cnblogs.com/ZSY-blog/p/12638459.html
Copyright © 2011-2022 走看看