1. 程式人生 > >找出一個字串中第一個只出現一次的字元

找出一個字串中第一個只出現一次的字元

題目:在字串中找出第一個只出現一次的字元。如輸入 “abaccdeff”,則輸出b。
思路分析:
(1)由於題目與字元出現的次數相關,那麼是不是可以統計每個字元在該字串中出現的次數?要達到這個目的,我們需要一個數據容器來存放每個字元出現的次數。在這個容器中可以根據字元來查詢它出現的次數,也就是說這個容器的作用是把一個字元對映成一個數字。在常用的資料容器中,雜湊表正是這個用途。
(2)我們可以定義雜湊表的鍵值( key)是字元,而值(Value)是該字元出現的次數。同時我們還需要從頭開始掃描字串兩次。第一次掃描字串時,每掃描到一個字元就在雜湊表的對應項中把次數加1。接下來第二次掃描時,每掃描到一個字元就能從雜湊表中得到該字元出現的此時。這樣第一個只出現一次的字元就是符合要求的輸出。
(3)由於本題的特殊性,我們只需要一個非常簡單的雜湊表就能滿足要求。字元(char)是一個長度為8的資料型別,因此總共有256種可能。於是我麼建立一個長度為256的陣列,每個字母根據其 ASCII 碼值作為陣列的下標對應陣列的一個數字,而陣列中儲存的是每個字元出現的次數。這樣我們就建立了一個大小為256,以字元 ASCII 碼為鍵值的雜湊表。
(4)注意點:因為C/C++中的char有三種類型:char、signed char、unsigned char。char型別的符號是由編譯器指定的,一般是有符號的,在對字元進行hash時,應該先將字元轉為無符號型別;否則當下標為負值時,就會出現越界訪問。

具體實現如下:

#include <iostream>
using namespace std;

char FirstNotRepeatingChar(char *s)
{
    if (s == NULL)
        return '\0';

    const int size = 256;
    unsigned int count[size]; // 可用 unsigned int count[size] = {0}; 將陣列中每一個元素都初始化為0。
    for (int i = 0; i < size; i++) // 可能上述方法,不一定對所有編譯器都適用,所以採用迴圈的方式更穩妥。
count[i] = 0; char *pKey = s; while (*pKey != '\0') count[(unsigned char)*(pKey++)]++; pKey = s; while (*pKey != '\0') { if (count[(unsigned char)*pKey] == 1) return *pKey; pKey++; } return '\0'; } int main(int argc, const char
* argv[]) { char str[] = "abaccdeff"; printf("%c\n", FirstNotRepeatingChar(str)); return 0; }