2017-10-16 75 views
0
private static int getTotalWordValue(String word) { 
    int totalWordValue = 0; 

    // Code that produces correct results. 
    for(int i=0; i < alpha.length(); i++) { 
     char letter = alpha.charAt(i); 
     for(char ch: word.toCharArray()) { 
      if(letter == ch) { 
       totalWordValue += i+1; 
      } 
     } 
    } 

    // Code that produces incorrect results. 
    totalWordValue = 0; 
    for(int i=0; i < alpha.length(); i++) { 
     String letter = String.valueOf(alpha.charAt(i)); // <-- here? 
     if(word.indexOf(letter) != -1) { 
      totalWordValue += i+1; 
     } 
    } 

    return totalWordValue; 
} 

運行上述代碼解決Project Euler Problem 42,我得到不同的結果。上面顯示的第一個'for'循環輸出正確的結果,第二個'for'循環輸出不正確的結果。搜索char []中的char與使用String.indexOf()方法搜索String有什麼區別?

上面的代碼需要一個字符串並返回其字值。例如,該字SKY將返回的55字的值作爲在該單詞中的字母添加如下(從1開始):

  • S = 19(字母表中的19位)
  • K = 11 (字母表的第11位)
  • Y = 25(字母表的第25位)。

19 + 11 + 25 = 55。

我降低了問題上述代碼和不明白爲什麼發生這種情況。也許我錯過了與Java String類及其方法相關的重要信息。

我在Windows 10上運行的Java 8在Eclipse Neon.3版本(4.6.3)

+0

不確定你的問題到底是什麼。你能僅發佈特定的代碼嗎? – Ravi

+0

使用第一個代碼塊和第二個代碼塊有什麼區別?對我而言,他們應該基本上產生相同的總詞語價值。但是當在單詞列表上運行時,它們不會達到相同的結果。 – Kwistech

回答

1

這兩段代碼是完全不同的。

在這兩種情況下,您都有一個外部循環,它提供變量letter中的字符串alpha的每個字符。

在第一種情況下,你就必須穿過運行串word的每性格和計數letter匹配發生內部循環。當內環已經計數發生letterword,外循環移動到下一個letter

在第二種情況下,沒有內部循環。每次繞外環使用word.indexOf(letter)嘗試查找首次出現的索引letterword。如果有的話,你提前計數。無論哪種方式,你現在完成letter和外層循環移動到下一個letter。在word中可能還有其他出現的letter,但這種情況並未嘗試找到它們並對它們進行計數。

0

indexOf有4個重載方法和除character參數其中之一,返回第一次出現的索引字符序列中的字符。

現在,來找你的問題。在您的場景中,indexOfcharAt將表現相同,因爲您只傳遞字符。而且,因爲內部,但是,想象一下,你有一個String,你想檢查並從另一長的String得到它的索引。那你會怎麼做?有indexOf

1

對於包含多次字母的單詞的第二個實現中的單詞值不正確。例如WOOD, 第一種方法將計算3 + 14 + 14 + 22,但第二種方法會計算3 + 14 + 22.

爲什麼?在的字符的第一個方法迭代:

for(char ch: word.toCharArray()) { 
    if(letter == ch) { 
     totalWordValue += i+1; 
    } 
} 

第二種方法迭代的字母表的字符:

for(int i=0; i < alpha.length(); i++) { 
    String letter = String.valueOf(alpha.charAt(i)); // <-- here? 
    if(word.indexOf(letter) != -1) { 
     totalWordValue += i+1; 
    } 
} 

所以在例如「WOOD」, 「O」只計算一次,反而兩次。


順便說一句, 轉換爲String在這裏毫無意義:

String letter = String.valueOf(alpha.charAt(i)); 
if(word.indexOf(letter) != -1) { 

一種更好的方式來寫同樣的事情:

char letter = alpha.charAt(i); 
if (word.indexOf(letter) != -1) { 

(但實施仍然是不正確的。)


最後, 如果字母是英文AZ,然後更快的實現是可能的:

int totalWordValue = 0; 
for (char c : word.toCharArray()) { 
    if ('A' <= c && c <= 'Z') { 
    totalWordValue += (c - 'A') + 1; 
    } 
} 

return totalWordValue; 
0

我知道這並不一定能解決你的問題對上述方法之間的差異,但其他人對此已有足夠的回答。

你想要在字符串的字母位置的總和嗎?我們可以在一個循環中做一些算術運算,而不會增加內部循環或常量的額外開銷。

像這樣:

public static int getWordValue(String word) { 
    int value = 0; //total word value 
    for(char c : word.toLowerCase().toCharArray()) { //iterate over character array of lower case string 
      int charAsInt = (int) c; //cast char to int, giving the ASCII value 
      if(charAsInt <= 122 && charAsInt >= 97) { //122 is the ASCII value of 'z', and 97 is 'a' 
       value += (charAsInt - 96); //only subtract 96 because we want 'a' to be 1, not 0 
      } 
    } 
    return value; 
} 

如果現在這個工作的原因尚不清楚給你,它會根據檢查的ASCII十進制表變得明顯。我們來檢查一下。

ASCII to decimal table

請記小寫字母 'a' 和小寫字母 'Z' 的值。它們分別是我們的下限和上限。我們簡單地遍歷每個小寫字符,將其轉換爲ASCII十進制值,並使用int強制轉換。然後我們用'a'的值減去我們的ASCII值,減去1。

相關問題