以下是我正在处理的元胞自动机的代码:
public class Life1D {
private Rule rule;
private int stepCount;
public static void main (String [ ] args) {
Life1D simulation = new Life1D ( );
simulation.processArgs (args);
simulation.producePBM ( );
}
// 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, prev_string.charAt(0), prev_string.charAt(1));
} else if (j == width-1) {
next_string += rule.output(prev_string.charAt(width-2), prev_string.charAt(width-1), 0);
} else {
String rule_input = prev_string.substring(j-1, j+2);
int first = rule_input.charAt(0);
int second = rule_input.charAt(1);
int third = rule_input.charAt(2);
next_string += rule.output(first, second, third);
}
}
// 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 = Integer.toBinaryString(ruleNum);
}
// 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 int output (int a, int b, int c) {
return rulebin.charAt(7 - 4*a + 2*b + c);
}
}
运行时出现以下错误消息:
P1 7 4
0 Exception 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:90)
at Life1D.producePBM(Life1D.java:35)
at Life1D.main(Life1D.java:9)
到底是什么?为什么我会收到此错误,我该如何解决?我一直试图找出错误数小时,如果能得到帮助,这将是一件幸事。
答案 0 :(得分:0)
在此特定部分中,您将整数转换为二进制字符串:
rulebin = Integer.toBinaryString(ruleNum);
现在假设你的参数是:
第一个参数= 12
第二个参数=任何数字
现在,当此代码将此数字转换为二进制字符串时,您将获得:
rulebin =“1100”(长度4)
现在在这个函数中:
public int output (int a, int b, int c) {
return rulebin.charAt(7 - 4*a + 2*b + c);
}
当a = b = c = 0时,此函数将尝试访问“rulebin的字符8”,但是你的规则的长度为4.这就是为什么你得到字符串索引超出约束的异常。
注意:我不确定您是否对输入参数设置了任何限制,但这可能是一个潜在的问题。
答案 1 :(得分:0)
没有!问题是你将char而不是int传递给
public int output (int a, int b, int c) {
return rulebin.charAt(7 - 4*a + 2*b + c);
}
我试过了,当prevString.charAt(0)和prevString.charAt(1)为0时,它向输出方法发送那些参数(0,48,48)(尝试调试它,你会) 这导致指数超出范围!
并且转换为二进制字符串也不会返回7位格式..
<强>更新强>
public class Lif1ID {
private Rule rule;
private int stepCount;
public static void main (String [ ] args) {
Lif1ID simulation = new Lif1ID ( );
simulation.processArgs (args);
simulation.producePBM ( );
}
// 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) {
// take a look at the 'getNumericValue' Method.. in your version it didn't pass 0 or 1, now it does..
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(prev_string.charAt(width-2), 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);
}
}
// 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) { // here you want to return a char, no?
return rulebin.charAt(7 - 4*a + 2*b + c); // there is a problem with your formula
}
}