第一个只出现一次的字符

来源:互联网 发布:mac隐藏dock 怎么恢复 编辑:程序博客网 时间:2024/06/05 15:43

这个题目可以看做是一类题型。就是从一个数组中找出不重复的第一个或是全部的数,或是在一个字符串当中找。另外还可以做成大数据的情况,例如,给你一亿或是几亿个数,32位的int类型,让你找出所有的不重复的数。

基本思路有几个,第一个推荐的方法是位图BitMap,哈希表Hashtable。第二个方法是异或法,此方法在剑指offer中有介绍。下面详细来分析如何解决此类问题。

HashTable法

对于查找第一个只出现一次的字符,我们可以用一个数据容器来存放每一个字符出现的次数,在这个容器中,可以根据字符来查找它出现的次数,也就是说把字符映射成一个数字。

我们可以定义一个哈希表,他的键值(Key)是字符,而值(Value)是该字符出现的次数。同时需要扫描字符数组两次。第一次用于统计所有字符出现的次数。第二遍时,可以输出第一个只出现一次的字符,也可以设置输出所有只出现一次的字符。

下面关键一步是定义Hashtable。因为是字符,所以只有256种情况,不考虑中文字符。那么我们就建一个256大小的数组,用字符的ASCII码值作为下标,即该字符的ASCII码值就是其在数组中的位置。好的,代码如下:

char FindNotRepeatedChar(char *string){if (string == NULL)return '\0';const int Tablesize = 256;unsigned int HashTable[Tablesize] = {0};char* pHash = string;while ((*pHash) != '\0'){HashTable[*pHash]++;pHash++;}pHash = string;while (*pHash != '\0'){if (HashTable[*pHash] == 1)
<span style="white-space:pre"></span>{<span style="white-space:pre"></span>return *pHash;
<span style="white-space:pre"></span>break;<span style="white-space:pre"></span>
<span style="white-space:pre"></span>}pHash++;}return '\0';}


好下面来讨论下大数据量时,用BitMap来压缩统计。

BitMap

代码参考:

# include<stdio.h>    # include<string.h>      const int N = 26;    int bit_map[N];      void findNoRepeat(char *src)    {        int pos;        char *str = src;        int i ,len = strlen(src);          //统计        for(i = 0 ; i < len ;i ++)            bit_map[str[i]-'a'] ++;          //从字符串开始遍历 其bit_map==1 那么就是结果        for(i = 0 ; i < len ; i ++)        {            if(bit_map[str[i]-'a'] == 1)            {                printf("%c",str[i]);                return ;            }        }    }      int main()    {           char *src = "abaccdeff";        findNoRepeat(src);        printf("\n");        return 0;    }  


题目可以是: 在2.5亿个整数中找出不重复的整数,内存不足以容纳这2.5亿个整数。

    方案1:采用2-Bitmap(每个数分配2bit,00表示不存在,01表示出现一次,10表示多次,11无意义)进行,共需内存2^32*2bit=1GB内存,还可以接受。然后扫描这2.5亿个整数,查看Bitmap中相对应位,如果是00变01,01变10,10保持不变。扫描遍历完事后,查看bitmap,把对应位是01的整数输出即可。

    方案2:也可采用上题类似的方法,进行划分小文件的方法。然后在小文件中找出不重复的整数,并排序。然后再进行归并,注意去除重复的元素。


0 0