2011-03-07 131 views
0

好吧,所以我寫了這個程序,它將計算某些字母和空格,我希望它執行的操作是讓用戶不斷輸入短語,並繼續循環直到用戶輸入quit終止。我無法看到放置while循環的位置。我知道我應該在while循環下嵌套所有的循環,當我這樣做時,程序進入無限循環。無限循環,不會以while循環結束

import java.util.Scanner; 

public class Count 
{ 
    public static void main (String[] args) 
    { 
     String phrase; // a string of characters 
     int countBlank; // the number of blanks (spaces) in the phrase 
     int length;  // the length of the phrase 
     char ch;   // an individual character in the string 
     int countA=0,countE=0,countS=0,countT=0; 


    Scanner scan = new Scanner(System.in); 
     // Print a program header 
     System.out.println(); 
     System.out.println ("Character Counter"); 
     System.out.println(); 

     // Read in a string and find its length 
     System.out.print ("Enter a sentence or phrase or enter (Quit) to quit: "); 
     phrase = scan.nextLine(); 
while(!phrase.equalsIgnoreCase ("Quit")) 
{ 
     length = phrase.length(); 

      // Initialize counts 
      countBlank = 0; 

     // a for loop to go through the string character by character 

      for (int i = 0; i < phrase.length(); i++) 
     { 
      if(phrase.charAt(i) == ' ') countBlank++; 

      switch(ch=phrase.charAt(i)) 
      { 
      case 'a': 
      case 'A': countA++; 
      break; 

      case 'e': 
      case 'E': countE++; 
      break; 

      case 's': 
      case 'S': countS++; 
      break; 

      case 't': 
      case 'T': countT++; 
      break; 

     } 
    } 


     // Print the results 
     System.out.println(); 
     System.out.println ("Number of blank spaces: " + countBlank); 
     System.out.println ("Number of a: " + countA); 
     System.out.println ("Number of e: " + countE); 
     System.out.println ("Number of s: " + countS); 
     System.out.println ("Number of t: " + countT); 
     System.out.println(); 

    } 
} 
} 
+0

首先,採取「退出」,而不是「退出」,並且您應該使用ToLower()以確保tolower之後的「quItE」=「quit」。 – 2011-03-07 20:39:30

+0

不要在循環內「初始化」某些東西,它會在每個循環中重新初始化 – 2011-03-07 20:40:12

回答

5

在while循環中,你永遠不會讀下一行。您需要添加

phrase = scan.nextLine(); 

'for'循環後,但仍在'while'循環中。否則,短語將始終保持您第一次讀入的內容。

+0

ü是否意味着我應該將while循環嵌套在for循環中? – 2011-03-07 20:40:51

+0

for循環遍歷命令行中提供的字符串中的每個字符。您希望不斷從用戶那裏讀取新字符串,直到用戶輸入「退出」。考慮你的循環結構。雖然用戶還沒有進入「退出」,但您希望循環輸入其中的每個字符。然後,你想從命令行讀取下一個字符串,看看它是否等於「退出」,如果它是跳出循環。你應該保持for循環和while循環的原樣。您只需要添加對scan.nextLine()的調用,以便該短語更新爲用戶輸入的下一個字符串。 – 2011-03-07 20:42:22

+0

所以你的意思是保持我現在擁有的並添加一個短語= scan.nextLine(); for循環裏面?我試過之前,但之後我輸入一個短語,它不會運行的過程 – 2011-03-07 20:58:32

0

您應該在while循環結束時掃描一行新行。現在你的循環的構造方式,你不斷迭代相同的輸入。

phrase = scan.nextLine(); 
while(!phrase.equalsIgnoreCase ("Quit")){ 
    // do stuff 
    // ... 
    phrase = scan.nextLine(); 
} 
0
// Read in a string and find its length 
System.out.print ("Enter a sentence or phrase or enter (Quit) to quit: "); 

while (true) { 
    phrase = scan.nextLine(); 
    if (phrase.equalsIgnoreCase("Quit")) break; 

    // Initialize your counter variables here 

    length = phrase.length(); 
    // and so on... 
} 
+0

好吧,我看到了,謝謝 – 2011-03-07 20:42:51

+0

字符計數器 輸入一個句子或短語或輸入(退出)退出:什麼? 大量的空格:2 的數量:1點 電子商務數目:2 S的數目:0 的T數量:2 你好你怎麼樣 空格數:3 的數:2 e的電話號碼:4 s的數量:0 t的數量:2 我現在有這個問題,第一個它正確計數,但在我輸入第二個短語後,結果被添加到第一個。可以看到你的錯誤? – 2011-03-07 20:51:38

+0

您的所有計數變量都保持其舊值。您需要在while循環開始時全部重置爲0。 – 2011-03-07 20:57:53

1

複製實在是太差了,並試圖避免duplicaiton可能是你所遇到(不想把scan.nextLine兩次,有很好的本能)的問題。我認爲Philippe的答案是正確的。

讓我作弊,並重新寫菲利普的回答在一對夫婦不同的方式

do { 
    phrase = scan.nextLine(); 
    // do stuff 
    // ... 

} while(!phrase.equalsIgnoreCase ("Quit")); 

這將消除重複,但會導致「東西」被「做」,即使這句話是「退出」,那也不好 - 而且增加休息會毀了它。

while(true) { 
    phrase = scan.nextLine(); 
    if(!phrase.equalsIgnoreCase ("Quit")) 
     break; 
    // do stuff 
} 

這完美的作品,但同時(真)使得一些人真的很不舒服 - 這是一個宗教,有些人在年輕的時候學習,不能克服,所以你可能不希望推動這一 - 他們如何確信,這比其他解決方案更可能導致「無限循環」,因爲它們在功能上是正確的,所以完成垃圾,但它也隱藏了可能令人討厭的循環退出標準。

另外一個是有效的,但讓某些人不舒服:

while((phrase = scan.nextLine()).equalsIgnoreCase ("Quit")) { 
    // do stuff 
} 

其實很少有人在Java中使用此 - 我從來沒有使用它,我不能完全確定,因爲我不想它是有效的」不要用它,但我認爲=仍然返回要操作的值。無論如何,如果我不得不測試它是非常罕見的,那麼讓其他人花費更多的時間來看待它,這是非常罕見的,這是不好的。

那麼最好的解決方案是什麼?也許把它分解成方法調用:

private string phrase; 

boolean readPhrase() { 
    phrase=scan.nextLine(); 
    return !phrase.equalsIgnoreCase("Quit"); 
} 

while(readPhrase()) { 
    // do stuff 
} 

我知道這好像更多的工作,但如果你打破東西出來成可用塊這樣的習慣,讓你會從長遠來看,更快樂。您現在擁有更多的模塊化,可理解的代碼 - 並且沒有任何成本(只要它們是簡單,簡短,易於理解的方法,而且您不重複邏輯,從不認爲更多的方法是成本)。老實說,如果你打算繼續使用它來做任何真實的事情,我甚至可能會創建一個包含字符串變量和.countCharacter(「」)的.read()方法的「phrase」類。方法。這將使你的代碼看起來像這樣:

while(phrase.read()) { 
    System.out.println("Number of a="+phrase.countCharactr("a")); // assume that countCharacter does a toLower() 
    System.out.println("Number of a="+phrase.countCharactr("e")); 
    ... 
} 

這突然是非常可讀和緊湊。

另請注意,當你像這樣減少代碼時,其他模式變得容易識別。在這種情況下,你甚至可能會發現,你可以分解出重複線的上方,因爲他們只有在每種情況下的單個字符改變:

char[] chars="aest".toCharArray(); 

while(phrase.read()) 
    for(char c : chars) 
     System.out.println("Number of "+c+"="+phrase.countCharactr(c)); // assume that countCharacter does a toLower() 
// this is untested and some of the conversions/methods/etc may need tweaking.  

你的整個「主」減少到幾行簡單的輔助類。是不是更好?

對不起,過分分析。沒有工作,開始錯過編碼。

+0

[code] while((phrase = scan.nextLine())。equalsIgnoreCase(「Quit」)){ // do stuff }'code' 這個答案是最漂亮的,也是我最常見的一個像緩衝讀者一樣的類似情況。 – keepitreall89 2011-03-07 21:38:27

+0

@ keepitreall89你會聽到人們抱怨每個解決方案。最具可讀性的幾乎總是不會被人們稱作「優雅」或「漂亮」。最可讀的可能是最後一個(儘管名字字符是一個不錯的選擇,應該使用「charsToScan」),它可以讓更多的方法/類更清晰/更具可讀性。根據我的經驗,可讀性幾乎可以擊敗所有其他特性,但這只是我的經驗 – 2011-03-08 10:56:24

+0

是的,我知道這是更多的程序員的偏好,因爲有幾種方法來解決每個問題,我自己我走在代碼的行和寬版本的短,然後評論來解釋什麼正在發生。 – keepitreall89 2011-03-08 16:21:35