控制流程在嵌套循环中如何处理break语句? (Java)

huangapple go评论83阅读模式
英文:

How does the control flow for break statements work in nested loops? (Java)

问题

我已经在Java中编程一段时间了,但今天遇到了一些我认为很奇怪的事情。我记得当在嵌套循环中使用break语句时,控制流会返回到外部循环的头部。就像这个图示演示的那样。

控制流程图(我知道你们喜欢内联,但根据声誉要求,我不被允许)

也许,这个图示和我的回忆是不正确的。我之所以这样说,是因为当我运行以下代码时,控制流将每个标记添加到LinkedList listOfAllPalindromes中。我已经验证包含break语句的if块在应该访问它时确实被访问。所以简而言之,我的记忆是错误的吗?当控制流程达到break语句时,它是否应该跳转到listOfAllPalindromes.add(token)像它看起来正在做的那样?

public static void main(String[] args) throws FileNotFoundException {

    File dictionary = new File("english3.txt");
    Scanner s = new Scanner(dictionary);
    String token;
    LinkedList<String> listOfPalindromes = new LinkedList<>();

    while (s.hasNext())
    {
        token = s.next().toLowerCase();

        for (int i = 0; i <= (token.length()-1)/2; i++)
        {
            if(token.charAt(i) != token.charAt(token.length()-(i+1)))
            {
                break;
            }
        }
        
        listOfPalindromes.add(token);
    }

    for(String word : listOfPalindromes)
    {
        System.out.println(word);
    }
}
英文:

I have been programming in Java for a while, however I ran into something today that I thought was odd. I recall that when a break statement is used in a nested loop the control flow returns to the header of the outer loop. As demonstrated by this graphic.

Control Flow Diagram (I know you guys like it inline, but per reputation requirements I am not allowed)

Perhaps, this graphic and my recollection is incorrect. I say this because when I run the following code, the control flow adds every token to the LinkedList listOfAllPalindromes. I have verified that the if-block that contains the break statement is being accessed when it is supposed to be. So in short, is my memory wrong, is the control flow when it hits the break statement supposed to jump to listOfAllPalindromes.add(token) like it appears to be doing?

 public static void main(String[] args) throws FileNotFoundException {

    File dictionary = new File(&quot;english3.txt&quot;);
    Scanner s = new Scanner(dictionary);
    String token;
    LinkedList&lt;String&gt; listOfPalindromes = new LinkedList&lt;&gt;();

    while (s.hasNext())
    {
        token = s.next().toLowerCase();

        for (int i = 0; i &lt;= (token.length()-1)/2; i++)
        {
            if(token.charAt(i) != token.charAt(token.length()-(i+1)))
            {
                break;
            }
        }
        
        listOfPalindromes.add(token);
    }

    for(String word : listOfPalindromes)
    {
        System.out.println(word);
    }
}

答案1

得分: 1

你应该使用带有标签的 continue,而不是像这样使用 break

Scanner s = new Scanner("lever level canoe kayak carrace racecar mademoiselle madam");
String token;
LinkedList<String> listOfPalindromes = new LinkedList<>();

L: while (s.hasNext()) {
    token = s.next().toLowerCase();

    for (int i = 0; i <= (token.length() - 1) / 2; i++) {
        if (token.charAt(i) != token.charAt(token.length() - (i + 1))) {
            continue L;
        }
    }

    listOfPalindromes.add(token);
}

for (String word : listOfPalindromes) {
    System.out.println(word);
}

output

level
kayak
racecar
madam
英文:

You should use continue with a label instead of break like this.

Scanner s = new Scanner(&quot;lever level canoe kayak carrace racecar mademoiselle madam&quot;);
String token;
LinkedList&lt;String&gt; listOfPalindromes = new LinkedList&lt;&gt;();

L: while (s.hasNext()) {
    token = s.next().toLowerCase();

    for (int i = 0; i &lt;= (token.length() - 1) / 2; i++) {
        if (token.charAt(i) != token.charAt(token.length() - (i + 1))) {
            continue L;
        }
    }

    listOfPalindromes.add(token);
}

for (String word : listOfPalindromes) {
    System.out.println(word);
}

output

level
kayak
racecar
madam

答案2

得分: 0

使用标签来更好地理解循环的控制流程。

当它遇到break语句时,应该跳出for循环。

英文:

use labels to loops for better understanding on control flow of loops.

It should jump come out of for loop as it hits break statement

答案3

得分: 0

jls-14.15

> 不带标签的break语句试图将控制转移给最内层的enclosing switch、while、do或for语句;这个enclosing statement,也被称为break target,随后立即正常完成。

所以,回答你的问题,break语句会中断你的for循环,然后会执行listOfPalindromes.add(token)这一行。

英文:

From jls-14.15:

> A break statement with no label attempts to transfer control to the
> innermost enclosing switch, while, do, or for statement; this
> enclosing statement, which is called the break target, then
> immediately completes normally.

So, answering your question the break statement will break your for loop, and the listOfPalindromes.add(token) line will be executed.

答案4

得分: 0

你可以使用其他方法来检查是否为回文,然后在你的第一个循环中调用这个方法。
示例:

public static void main(String[] args) throws FileNotFoundException {

    File dictionary = new File("english3.txt");
    Scanner s = new Scanner(dictionary);
    String token;
    LinkedList<String> listOfPalindromes = new LinkedList<>();

    while (s.hasNext()) {
        token = s.next().toLowerCase();

        if (isPalindrome(token)) {
            listOfPalindromes.add(token);
        }
    }

    for (String word : listOfPalindromes) {
        System.out.println(word);
    }
}

private static boolean isPalindrome(String token) {
    for (int i = 0; i <= (token.length() - 1) / 2; i++) {
        if (token.charAt(i) != token.charAt(token.length() - (i + 1))) {
            return false;
        }
    }
    return true;
}

我没有检查代码的正确性,只是通过使用 break 来解决问题。

英文:

You can resolve your problem using other method to check is palindrome, and then from your first looop fire this method.
Example:

public static void main(String[] args) throws FileNotFoundException {

    File dictionary = new File(&quot;english3.txt&quot;);
    Scanner s = new Scanner(dictionary);
    String token;
    LinkedList&lt;String&gt; listOfPalindromes = new LinkedList&lt;&gt;();

    while (s.hasNext())
    {
        token = s.next().toLowerCase();

        if(isPalindrome(token)) {
        	listOfPalindromes.add(token);
        }
    }

    for(String word : listOfPalindromes)
    {
        System.out.println(word);
    }
}

private static boolean isPalindrome(String token) {
	for (int i = 0; i &lt;= (token.length()-1)/2; i++)
    {
        if(token.charAt(i) != token.charAt(token.length()-(i+1)))
        {
            return false;
        }
    }
	return true;
}

I didn't check is code correctly, only resolve problem with break

huangapple
  • 本文由 发表于 2020年8月9日 04:43:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/63320054.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定