2009-11-28 110 views
1

我有一個Java問題:我正在編寫一個程序來讀取一個字符串並顯示該字符串中的字符數。我找到了一些示例代碼,但我不太瞭解最後一部分 - 任何人都可以幫忙嗎?顯示字符串中的字符數

int[] count = countLetters(line.toLowerCase()); 

for (int i=0; i<count.length; i++) 
{ 
    if ((i + 1) % 10 == 0) 
      System.out.println((char) ('a' + i)+ " " + count[i]); 
    else 
     System.out.print((char) ('a' + i)+ " " + count[i]+ " "); 
} 

public static int[] countLetters(String line) 
{ 
    int[] count = new int[26]; 

    for (int i = 0; i<line.length(); i++) 
    { 
     if (Character.isLetter(line.charAt(i))) 
      count[(int)(line.charAt(i) - 'a')]++; 
    } 

    return count; 
} 
+0

除非您有嚴格的要求和嚴格的輸入檢查,否則只要您輸入大量字母,數字,非US-ASCII字母,空格等各種字符,此代碼就會中斷...基本上任何不在「a」和「z」。 – Bombe 2009-11-28 20:08:27

回答

2

你的最後一個循環是:

對於每一個我們測試它是否是一個字母,如果是,我們增加相對於字符計數器字符。這意味着'a'是0,'b'是1 ...(換句話說,'a'是'a' - 'a'是0,'b'是'b' - 'a',它是1 ...)。

這是計算字符串中字符出現次數的常用方法。

1

您發佈的代碼不是計算字符串的長度,而是計算出小寫字符串中出現的字母的數量。

Character.isLetter(line.charAt(i)) 

檢索到的字符在i位置,並返回true如果它是一個字母。

count[(int)(line.charAt(i) - 'a')]++; 

在指數character - 'a'加計數,這是026

函數的結果是一個包含每個字母計數的26個整數的數組。

for循環在計數陣列結束打印輸出每第10個計數,並使用

(char) ('a' + i) 

來打印計數屬於信。

0

我猜你正在計算字母的出現次數,而不是字符('5'也是一個字符)。

最後一部分:

for (int i = 0; i<line.length(); i++) 
{ 
    if (Character.isLetter(line.charAt(i))) 
     count[(int)(line.charAt(i) - 'a')]++; 
} 

它遍歷每個字符的輸入線和檢查它是否是一個字母。如果是,則增加該信件的計數。計數保存在一個由26個整數組成的數組中(對於拉丁字母表中的26個字母)。字母'a'的計數保持在索引0處,字母'b'在1處,'z'在25處。爲了得到索引,代碼從字母值中減去值'a'(每個字符不僅是字符/字形,也是數字值)。所以如果這個字母是'a',它就會減去'a'的值,它應該是0等等。

0

在方法countLetters中,for循環遍歷該行中的所有字符。 if檢查以確保它是一個字母,否則將被忽略。

line.charAt()在位置i產生單個字符。這種類型是char

現在深入Java內部,char只是一個對應於字符代碼的數字。小寫'a'的字符代碼爲97,'b'爲98,依此類推。 (int)強制從char轉換爲int。所以我們取字符代碼,假設它是一個'b',所以代碼是98,我們減去'a'的代碼,即97,所以我們得到偏移量1(從字母表開始)。對於字母表中的任何字母,偏移量將介於0和25(含)之間。

因此,我們使用該偏移量作爲索引進入數組count並使用++來增加它。然後,程序頂部的循環可以打印出計數。

頂部的循環使用反向「技巧」將這些從0到25的偏移量轉換回從a到z的字母。

0

'最後部分',循環的實現真的很難理解。關閉混淆;)這裏的計數方法的重構(一分爲二的方法,一般一個爲所有字符,並就只是小型大寫字母特殊:

public static int[] countAllASCII(String line) { 
    int[] count = new int[256]; 
    char[] chars = line.toCharArray(); 

    for (char c : chars) { 
    int index = (int) c; 
    if (index < 256) { 
     count[index]++; 
    } 
    } 

    return count; 
} 

public static int[] countLetters(String line) { 
    int[] countAll = countAll(line);   
    int[] result = new int[26];  
    System.arraycopy(countAll, (int) 'a', result, 0, 26); 

    return result; 
} 

總體思路:在countAll方法只是計數所有的字符。是的,數組更大,但是在這些維度中,沒有人關心今天優點:我不必測試每個char。第二種方法只是將感興趣的區域複製到新的(結果)數組中並返回它。

編輯

我已經改變了我的代碼少解除好友關係以及評論。無論如何,謝謝Bombe。

+0

使用非US-ASCII字符將會失敗。歡迎在1996年。哦,等等,這是2009年,你仍然認爲一個字符只有8位寬...... – Bombe 2009-11-28 20:05:05