Java:Cellular Automaton中的Indexoutofbound

时间:2013-04-09 21:49:04

标签: automaton

以下是我正在处理的元胞自动机的代码:

更新

public class Lif1ID {

private Rule rule;
private int stepCount;

public static void main (String [ ] args) {
        Lif1ID simulation = new Lif1ID ( );
        simulation.processArgs (args);
        simulation.producePBM ( ); LINE 9
}

// Print, in Portable Bitmap format, the image corresponding to the rule and step count
// specified on the command line.
public void producePBM ( ) {
        int width = (stepCount*2+1);
        System.out.println("P1 " + width + " " + (stepCount+1));
        String prev_string = "";
        // constructs dummy first line of rule
        for (int i = 0; i < width; i++){
                if (i == stepCount+1){
                        prev_string += "1";
                } else {
                        prev_string += "0";
                }
        }
        // contructs and prints out all lines prescribed by the rule, including the first
        for (int i = 0; i < stepCount; i++) {
                String next_string = "";
                for (int j = 0; j < width; j++) {
                    // prints next line, one character at a time

                        System.out.print(prev_string.charAt(j) + " ");
                        // specifies cases for the edges as well as for normal inputs to Rule
                        if (j == 0) { 

                                next_string += rule.output(0, Character.getNumericValue(prev_string.charAt(0)), Character.getNumericValue(prev_string.charAt(1)));
                        } else if (j == width-1) {
                                next_string += rule.output(Character.getNumericValue(prev_string.charAt(width-2)), Character.getNumericValue(prev_string.charAt(width-1)), 0);
                        } else {
                                String rule_input = prev_string.substring(j-1, j+2);
                                int first = Character.getNumericValue(rule_input.charAt(0));
                                int second = Character.getNumericValue(rule_input.charAt(1));
                                int third = Character.getNumericValue(rule_input.charAt(2));
                                next_string += rule.output(first, second, third); LINE 43
                        }
                }
                // sets prev_string to next_string so that string will be the next string in line to be printed
                prev_string = next_string;
                System.out.println();
        }
}


// Retrieve the command-line arguments, and convert them to values for the rule number
// and the timestep count.
private void processArgs (String [ ] args) {
        if (args.length != 2) {
                System.err.println ("Usage: java Life1D rule# rowcount");
                System.exit (1);
        }
        try {
                rule = new Rule (Integer.parseInt(args[0]));
        } catch (Exception ex) {
                System.err.println ("The first argument must specify a rule number.");
                System.exit (1);
        }
        try {
                stepCount = Integer.parseInt (args[1]);
        } catch (Exception ex) {
                System.err.println ("The second argument must specify the number of lines in the output.");
                System.exit (1);
        }
        if (stepCount < 1) {
                System.err.println ("The number of output lines must be a positive number.");
                System.exit (1);
        }
   }
}

 class Rule {

private int a, b, c;
private String rulebin;

public Rule (int ruleNum) {
        rulebin = convertToBinary(ruleNum);
}

private String convertToBinary(int input) // get the binary presentation as you want
{                                         // if the input is 2 you'll get "00000010"
    String binary = "";
    for (int i = 0; i < 8; i++){
      if ((1 << i & input) != 0)
        binary += "1";
      else 
          binary+= "0";
    }
    binary = new StringBuffer(binary).reverse().toString();
    return binary;
}

// Return the output that this rule prescribes for the given input.
// a, b, and c are each either 1 or 0; 4*a+2*b+c is the input for the rule.
public char output (int a, int b, int c) {    
    return rulebin.charAt(7 - 4*a + 2*b + c); LINE 106
}

}

这是我输入规则30时有3个时间步长的错误消息:

java Life1D 30 3

更新错误消息:

P1 7 4
0 0 0 0Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String       index      out of range: 151
at java.lang.String.charAt(String.java:686)
at Rule.output(Life1D.java:106)
at Life1D.producePBM(Life1D.java:43)
at Life1D.main(Life1D.java:9)

代码中注明了相应的行。为什么我会收到此错误,我该如何解决?我一直试图找出错误数小时,如果能得到帮助,这将是一件幸事。

1 个答案:

答案 0 :(得分:0)

问题是Rule.output()需要三个int参数,但你在线上调用它是什么

next_string += rule.output(0, prev_string.charAt(0), prev_string.charAt(1));

实际上是一个int然后是2个字符。现在,实际的字符是'0',但是由于语言为你做的隐式转换,你得到的ASCII码为'0',即48,这就是传递给函数Rule.output()的内容。

现在,要解决此问题,您需要使用方法Character.getNumericValue(),如下所示:

next_string += rule.output(0, Character.getNumericValue(prev_string.charAt(0)), Character.getNumericValue(prev_string.charAt(1)));

不要忘记更改Rule.output()

的其他两个调用

但请注意,这不是代码中唯一的问题,因为我仍然会收到String index out of range: 7,因为调用Rule.output()方法的参数现在都是0,但是我已经回答了你原来的问题。如果您需要更多帮助,请告诉我。