2011-03-07 198 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