第一个只出现一次的字符---字符流中第一个不重复的字符

第一个只出现一次的字符

题目分析

面试题50-1:在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).

题目分析

1.使用哈希表来记录每个字符出现的次数,因为字符charchar为8位,总共有256个值,所有哈希表有256个元素,其中把字符的ASCIIASCII码作为哈希表的键值,而对应键值储存的是该字符出现的次数。
2.那么对给定的字符串进行两次遍历,第一遍收集信息,即统计每个字符串出现了多少次。第二次查找第一个出现一次的字符,即碰到第一个只出现了一次的字符就进行输出。

哈希表是一种常用的数据结构,这里我们使用哈希表把一个字符映射成一个数字。在STL中,map和unordered_map就实现了哈希表的功能,同样使用数组/vector来实现简单的哈希表。

  • 注释版
class Solution {
public:
    int FirstNotRepeatingChar(string str){
        int strSize = str.size();
        //处理错误输入
        if(strSize <= 0)return -1;
        //处理特殊输入
        if(strSize == 1)return 0;

        //使用vector做一个哈希表,记录每个字符出现的次数,全部初始化为0
        vector<int> hashTable(256,0);   //map<char,int> hashmap;  map的value为int时,默认初始化为0
        //范围for循环对输入字符串进行第一次遍历,统计每一种字符出现的次数
        for(auto s:str)
            //s对应的ASCII码作为键,s出现的次数作为值,组成键值对
            hashTable[s]++;    //string自动提升转换为int型(ASCII码),


        //对输入字符串进行第二次遍历
        for(int i = 0;i != strSize;i++){    //第二次遍历str(不是hashmap),根据str中的字符在hashmap中寻找值(次数)
            if(hashTable[str[i]] == 1)
                return i;
        }
        return -1;
    }
};

  • 无注释版
class Solution {
public:
    int FirstNotRepeatingChar(string str){
        if(str.empty())
            return -1;
        if(str.size() == 1)
            return 0;
        
        vector<int> hashmap(256,0);
        
        for(auto s : str)
            hashmap[s]++;      
        
        for(int i = 0; i < str.size();++i){    
            if(hashmap[str[i]] == 1)
                return i;
        }
        
        return -1;
    
    }
};

总结

  • 范围for循环的使用
  • 隐形的类型转换,string提升为int(ASCII码)
  • 建立一个256大小的哈希表,是因为:首先,建立一个128大小的哈希表即可。然后解释:字符在计算机中以ASCII码的形式存储,当字符作为数组下标时,其表示的下标值为该字符的ASCII码的十进制值。而ASCII码由8位表示,只有后面7位起作用,2^7为128,因此ASCII码共有128个字符,十进制范围为0127.)(建立256大小是因为char占一个字节(8位),无符号范围为0255,有符号就为-128~127。)
  • map的value为int时,默认初始化为0

字符流中第一个不重复的字符

题目分析

面试题50-2:请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。

思路分析

class Solution{
public:
  //Insert one char from stringstream
    string s;
    //vector <int> hash(256,0); //报错,不知为何?
    int hash[256]={0};    //如果只对部分元素初始化,剩下的未显式初始化的元素,将自动被初始化为零;
    void Insert(char ch){
        s += ch;
        hash[ch]++;    //hash数组记录每个字符出现的次数
    }
  
    //return the first appearence once char in current stringstream
    //遍历输出的流,根据hash数组由字符找到字符出现次数
    char FirstAppearingOnce(){
        int size=s.size();
        for(int i=0;i<size;++i){
            if(hash[s[i]]==1)
                return s[i];
        }
        return '#';
    }
 
};
发布了65 篇原创文章 · 获赞 25 · 访问量 2593

猜你喜欢

转载自blog.csdn.net/weixin_43892514/article/details/104878757