这是真·CS小白在coursera Princeton Algorithms上码的第一个作业,真是好心酸...作业网址如下:
http://coursera.cs.princeton.edu/algs4/assignments/percolation.html
由两个文件组成,Percolation和PercolationStats,后者中将实例化前者并完成相应的计算和模拟。
public class Percolation {
int[][] grid;
int ranN;
int N;
WeightedQuickUnionUF wuf;
public Percolation(int N) {
if (N <= 0) {
throw new IllegalArgumentException("N不可以小于等于0");
}
grid = new int[N][N];
for (int row = 0;row < N;row++) {
for (int col = 0;col < N;col++){
grid[row][col] = 0;
}
}
wuf = new WeightedQuickUnionUF(N*N);
}
public void open(int i, int j) {
if (i < 1 || i > N || j < 1 || j > N) {
throw new IndexOutOfBoundsException("Row or Col index out of bounds!");
}
grid[i-1][j-1] = 1;
}
public boolean isOpen(int i, int j) {
if (i < 1 || i > N || j < 1 || j > N) {
throw new IndexOutOfBoundsException("Row or Col index out of bounds!");
}
if (grid[i-1][j-1] == 1)
return true;
else
return false;
}
public boolean isFull(int i, int j) {
if (i < 1 || i > N || j < 1 || j > N) {
throw new IndexOutOfBoundsException("Row or Col index out of bounds!");
}
int parent = (i - 1) * N + j - 1;
if (isOpen(i ,j) && wuf.find(parent) < N && isOpen(1, parent+1))
return true;
else
return false;
}
public boolean percolates() {
for (int i = 1;i <= N;i++) {
if (isFull(N, i) == true)
return true;
}
return false;
}
public static void main(String[] args) {
return;
}
}
于是乎...为何我在PercolationStats里调用open(), isOpen()函数等,无论我的i, j是多少都会调用IndexOutOfBoundsException呢?感觉很困惑...
import java.lang.System;
public class PercolationStats {
static int N, T;
int rdRow, rdCol, rdN, openCount;
double percentage;
double[] group;
Percolation pc;
public PercolationStats(int N, int T) {
int num = N * N;
group = new double[T];
int i = 0;
while (i < T) {
pc = new Percolation(N);
openCount = 0;
while (pc.percolates() == false) {
do {
rdRow = StdRandom.uniform(1, N+1);
rdCol = StdRandom.uniform(1, N+1);
}
while (pc.isOpen(rdRow, rdCol) == false);
pc.open(rdRow, rdCol);
openCount++;
rdN = (rdRow-1) * N + rdCol - 1;
if (rdCol+1 <= N && pc.isOpen(rdRow, rdCol+1))
pc.wuf.union(rdN, rdN+1);
if (rdCol-1 >= 1 && pc.isOpen(rdRow, rdCol-1))
pc.wuf.union(rdN, rdN-1);
if (rdRow+1 <= N && pc.isOpen(rdRow+1, rdCol))
pc.wuf.union(rdN, rdN+N);
if (rdRow-1 >= 1 && pc.isOpen(rdRow-1, rdCol))
pc.wuf.union(rdN, rdN-N);
}
percentage = openCount / num;
group[i] = percentage;
i++;
}
}
public double mean() {
return StdStats.mean(group);
}
public double stddev() {
return StdStats.stddev(group);
}
public double confidenceLo() {
double Lo = this.mean() - 1.96*this.stddev()/Math.sqrt(T);
return Lo;
}
public double confidenceHi() {
double Hi = this.mean() - 1.96*this.stddev()/Math.sqrt(T);
return Hi;
}
public static void main(String[] args) {
N = Integer.parseInt(args[0]);
T = Integer.parseInt(args[1]);
PercolationStats PS = new PercolationStats(N, T);
System.out.println("mean = " + PS.mean());
System.out.println("stddev = " + PS.stddev());
System.out.print("95% confidence interval = " + PS.confidenceLo() + "," + PS.confidenceHi());
}
}
下面是我调用open()所用的类。初学java,在上princeton的算法课,结果第一个作业就亚历山大...以及...我在删掉IndexOutOfBoundsException的if后,运行java PercolationStats 200 100没有任何反应啊,这是怎么回事呢?小白一枚真心求教!如果有愿意点开coursera作业并帮忙分析原因的大神本人感激不尽!谢谢~~
问题出在构造函数上,你传入了 int N 的参数, 但是没有把这个N赋给 Percolation 的变量N,所以在后续判断的时候if (i < 1 || i > N || j < 1 || j > N)
这里面N始终为0。所以总是认为数组越界。
将构造函数改成以下就可以了,只是增加了this.N = N
的赋值语句。
public Percolation(int N) {
if (N <= 0) {
throw new IllegalArgumentException("N不可以小于等于0");
}
grid = new int[N][N];
for (int row = 0;row < N;row++) {
for (int col = 0;col < N;col++){
grid[row][col] = 0;
}
}
wuf = new WeightedQuickUnionUF(N*N);
this.N = N;
}
然后第二个问题,我大概看了一眼。你把if语句删掉之后,下面的代码就陷入死循环了
do {
rdRow = StdRandom.uniform(1, N+1);
rdCol = StdRandom.uniform(1, N+1);
}
while (pc.isOpen(rdRow, rdCol) == false);
isOpen函数一直返回是true,即grid所有的元素全都是0。这也不难理解,在这一步操作之前,你只是初始化了grid矩阵,但是没有做任何赋值运算。但是你在不断的返回一个随机的rdRow和rdCol去访问这个grid的元素,所以isOpen函数始终是返回true。
so……好好debug一下你的代码……多把几步的返回结果打印出来,你就知道为啥了。
Percolation 类的N赋值了吗?似乎没有,因此你的 N被默认赋值为0
`public void open(int i, int j) {
if (i < 1 || i > N || j < 1 || j > N) {
//i>N 一直成立 所以这个异常总是抛出
throw new IndexOutOfBoundsException("Row or Col index out of bounds!");
}`
你可以在
public Percolation(int N){
//在这里加个句
this.N = N;
......
}