检查循环是否在没有条件中断的情况下运行

时间:2015-03-07 23:58:53

标签: java

我目前正在编程。在这个任务中,我得到一个随机的Ascii图像。我的工作是将其转换为CSV格式。例如: ascii图片:

3
  **
******
  ** *+

csv格式:

3
2, ,2,*,2, 
6,*
2, ,2*,1, ,1,*,1,+

这是我的代码:

public static void imageToNumRep(File input, File output)
throws FileNotFoundException
{
    Scanner in = new Scanner(input);
    PrintStream out = new PrintStream(output);
    while(in.hasNextLine())
    {
        int count = 0;
        String text = in.nextLine();
        for (int i = 0; i <= text.length() -2; i++)
        {
            if (text.charAt(i) == text.charAt(i + 1))
            {
                count++;
            }
            if (text.charAt(i) != text.charAt(i + 1))
            {
                System.out.print(count+1+ "," + text.charAt(i)+ ", ");
                count = 0;
            }
        }
        int count2 = 0;
        for (int j = text.length()-1 ; j>0 ; j--)
        {

            if (text.charAt(j - 1) == text.charAt(j))
            {
                count2++;
            }
            if (text.charAt(j) != text.charAt(j - 1))
            {
                System.out.println(count2 + 1 + "," + text.charAt(j));
                count2 = 0;
                break;
            }
        }
    }
}

我想要做的是我将浏览图像中的每一行。 在每一行中,我将从第一个字符转到最后一个字符,或者从另一个方向转换。如果当前字符与下一个字符相同,我将有一个计数器来计算它。当我到达当前字符与下一个字符或前一个字符不同的点时,我将打印出计数和字符,指示我刚刚经历了多少个字符,然后重置计数。

问题是此代码仅适用于具有不同字符的行。当我通过从头到尾具有相同字符的一行时,我无法打印该行,因为我需要在该行中使用不同的字符才能打印。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

你的循环的一般结构,伪代码,就像这样(我会使用else,但它与你的示例代码的想法相同):

for every character in string {
    if some condition is true {
        ...
    } else {
        output "the condition is false";
        break;
    }
}

您遇到的问题是,如果某个条件对于字符串中的每个字符都为真(例如,所有字符都相同),您就会采取某些操作(例如,打印字符串)。当然,在你完成循环之后,你才能知道这一点。典型的方法是找到一些方法使循环外的信息可用。考虑一下,例如:

boolean atLeastOneFalse = false; // we'll use this flag...

for every character in string {
    if some condition is true {
        ...
    } else {
        output "the condition is false";
        atLeastOneFalse = true; // ...to track if our condition is false...
        break;
    }
}

if (!atLeastOneFalse) { // ... so we can tell if it was ever false or not when we're done checking.
    output "the condition was always true!";
}

这里我们使用一个标志来跟踪循环外循环中发生的事情。如果循环中的每次迭代条件都为真,那么我们的标志永远不会被触及,并且在循环之后将保持false。但如果条件为假,我们的旗帜就会设定。

上述方法非常简洁易读。沿着相同的行(从循环中获取信息)的第二种方法是在循环外声明索引计数器,然后在结束时检查它的值。例如:

int n;

for (n = 0; n < final value; ++ n) {
    if some condition is true {
        ...
    } else {
        output "the condition is false";
        break;
    }
}

if (n == final value) { // then we never broke out of the loop early, therefore the condition was never false
    output "the condition was always true!";
}

有一些方法可以重新组织上面的代码以减少行数,但我希望在不引入太多内容的情况下保持清晰。

现在,这种方式的缺点是它更容易出错。请注意&#34;最终值&#34;使用两次。这意味着,如果您修改您的代码,比如修改&#34;最终值&#34;是的,你有两个行要更新而不是只有一行。这增加了意外忘记更新一个的可能性。当然,如果你存储了&#34;最终价值&#34;在一个变量你可以消除这个,但我发现标志的方法更简单。您总是希望构建代码以最大限度地减少出错的可能性。

有时候你可能会看到第三种可能性,即检查你是否在循环内部的循环结束(例如if (n == final value - 1) { we made it through; }在循环内但在break之后)。我不打算举个例子,因为我不喜欢这种方法。从哲学上讲,它有一些更深层次的组织问题,在某些情况下也可能存在性能问题。我采用上面的旗帜方式。

希望这足以让您了解如何在您的应用程序中解决问题。

答案 1 :(得分:0)

package asciitocvs;

import java.io.*;
import java.util.Scanner;

public class itr {
    public static void imageToNumRep(File input, File output)
            throws FileNotFoundException {
        Scanner in = new Scanner(input);
        PrintStream out = new PrintStream(output);
        while (in.hasNextLine()) {
            int count = 0;
            String text = in.nextLine();
            for (int i = 0; i < text.length(); i++) {
                if (i+1<text.length() && text.charAt(i) == text.charAt(i + 1)) {
                    count++;
                }else{
                    System.out.print(count + 1 + "," + text.charAt(i) + (i+1<text.length()?", ":""));
                    count = 0;
                }
            }
            out.print("\n");
        }
        in.close();
        out.close();
    }
    public static void main(String[] args) throws FileNotFoundException {
        imageToNumRep(new File("ascii.txt"), new File("/dev/stdout"));
    }
}

确定i是或不是最后一个字符,问题已解决。