2012-11-09 55 views
0

這段代碼真的讓我困惑,它使用一些斯坦福圖書館爲Vector(數組)類。誰能告訴我int index = line [j] - 'a';爲什麼 - 'a'的目的是什麼?在C++字符串上的算術

void countLetters(string filename) 
{ 
Vector<int> result; 

ifstream in2; 
in2.open(filename.c_str()); 
if (in.fail()) Error("Couldn't read '" + filename + "'"); 

for (int i = 0; i < ALPHABETH_SIZE; i++) 
{ 
    result.add(0); // Must initialize contents of array 
} 

string line; 
while (true) 
{ 
    getLine(in, line); 
    // Check that we got a line 
    if (in.fail()) break; 

    line = ConvertToLowerCase(line); 
    for (int j = 0; j < line.length(); j++) 
    { 
     int index = line [j] - 'a'; 
     if (index >= 0 && index < ALPHABETH_SIZE) 
     { 
      int prevTotal = result[index]; 
      result[index] = prevTotal +1; 
     } 
    } 
} 
} 

的代碼的用途:

使用一個文件名,並打印字母表的每個字母出現在該文件的次數。由於要打印26個數字,CountLetters需要創建一個Vector。例如,如果文件是:

+1

據推測,它會找到一個字母是多遠的字母,但並不總是成立。 – chris

+1

整個代碼正在計算字母頻率。 'result ['c' - 'a']'是字符'c'出現在文件中的次數。 – irrelephant

回答

2

字符串中的字符使用字符集編碼...通常在英語系統中常見的硬件上使用ASCII編碼。你可以看到ASCII表在http://en.wikipedia.org/wiki/ASCII

在ASCII(和大多數其他字符集)中,代表字母的數字是連續的。所以,這是測試是否在字符數組line指數j人物自然的方式是一個字母:

line[j] >= 'a' && line[j] <= 'z' 

你的程序是相當於,在代數,那種意義上減去a從兩個邊(明知a是在字符集的第一個字符):

line[j] >= 'a' - `a` && line[j] <= 'z' - `a` 

line[j] >= 0 && line[j] <= 'z' - `a` 

更換 「< = z - a」 包含am當量:

line[j] >= 0 && line[j] < ALPHABET_SIZE 

其中ALPHABET_SIZE是26.此交易上知道z的依賴是你的性格的瞭解有多少個字符是在你的字符集設置的最後一個字符 - 無論是有點脆弱,但很好,如果你知道你處理一個衆所周知的,穩定的字符集編碼。

一種更好的方式來檢查信件是使用isalpha()斷言:http://www.cplusplus.com/reference/clibrary/cctype/isalpha/

+1

'ALPHABET_SIZE'實際上是一個壞主意,因爲它引入了第二個假設:字母表是連續的。這就是導致上述代碼在EBCDIC上失敗的錯誤假設,其中'''''''!= 1'。在法文/ ISO-8859-1中,類似的錯誤在'c'和'ç' – MSalters

+0

@MSalters之間出現:一對'> ='和'<='比較可以識別字母的想法對於非 - 連續的字母 - 沒有特定於ALPHABET_SIZE關於該問題。 –

2

「a」位於ASII字符的開頭。

int index = line [j] - 'a'; 如果(指數> = 0 & &索引< ALPHABETH_SIZE)

這兩行代碼是隻如果線[j]爲一個字符。

+0

但請注意,ASCII不能保證。 – chris