繁体   English   中英

线程“主”中的异常java.lang.IndexOutOfBoundsException:索引:0,大小:0

[英]Exception in thread “main” java.lang.IndexOutOfBoundsException: Index: 0, Size: 0

我正在尝试编写一个可以解决8-Puzzle问题的程序。我正在使用A *算法找到解决方案。 我已经多次检查了我的代码,还尝试进行一些更改。 甚至我的朋友都试图帮助我找到错误,但他们找不到。 我仍然不明白我哪里出了问题。我使用javadocs查看我是否做错了什么,即使那并不能解决我的问题。 我创建了三个类来解决此问题。

import java.util.*;
public class Solver implements Iterable<State>
{
    ArrayList<State> queue,solQueue;
    public int sol[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 0 } };
    int temp[][],i;
    int moves;
    int leastPriority,removeIndex;
    State removeTemp;
    public Solver(State initial)
    {
        queue = new ArrayList<State>();
        solQueue = new ArrayList<State>();
        queue.ensureCapacity(16);
        solQueue.ensureCapacity(16);
        temp = new int[3][3];
    i=1;
    leastPriority = 100;
    removeTemp=initial;
    queue.add(removeTemp);
    Iterator<State> qu = queue.iterator();
    while(removeTemp.m!=sol)
    {
        leastPriority = 100;
        i=0;
        queue.iterator();
        for (State s : queue) 
        {
            if((s.mh + s.count) <leastPriority)
            {
                leastPriority = (s.mh + s.count);
                removeIndex = i;
            }
            if(qu.hasNext())
                i++;
        }
        for(State s : removeTemp.neighbours() )
        {
            queue.add(s);
        }
        removeTemp=queue.remove(removeIndex);
        solQueue.add(removeTemp);
    }
    this.moves();
    this.solution();
}
public int moves() 
{
    System.out.print("Solution found out in "+ moves+" moves");
    moves = removeTemp.count;
    return moves;
}
public Iterable<State> solution() 
{
    for(State s : solQueue)
    {
        System.out.println(s.m);
        System.out.println("");
    }
    return solQueue;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Iterator iterator() {
    return null;
}
}

JVM引发异常。

     Exception in thread "main" java.lang.IndexOutOfBoundsException: Index:  0,Size: 0
     at java.util.ArrayList.rangeCheck(Unknown Source)
     at java.util.ArrayList.get(Unknown Source)
     at Solver.<init>(Solver.java:41)
     at Main.main(Main.java:13)

我不明白的是,当我明确声明它为16时,ArrayList的大小如何为1。

状态类具有启发式功能,该功能可提高算法的效率。以下是状态类。

  import java.util.ArrayList;
  import java.util.Iterator;

  public class State implements Iterable<State>
  {
   public int sol[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 0 } };
   int m[][], bi, bj, count, priority, si, sj;
   int i,j,tempm[][];
   int mh = 0;
   boolean isInitialState, isRepeatedState;
   State previousState, tempState;
   ArrayList<State> neighbourStates;

   public State(State s, int c, int[][] array) 
{
    neighbourStates = new ArrayList<State>();
    neighbourStates.ensureCapacity(16);

    tempState =this;
    m = new int[3][3];
    m=array;

    if (s == null) 
    {
        isInitialState = true;
        count = 0;
        previousState =null;
    } 
    else 
    {
        previousState = s;
        count = c+1;
    }

    this.findZero();
    this.manhattanHeuristic();
}

private void findZero() 
{
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
        {
            if(m[i][j]==0)
            {
                bi=i;
                bj=j;
            }
        }
}

private void manhattanHeuristic() {
    int n = 1;
    mh = 0;
    for (int i = 0; i < 3; i++)
        Z: for (int j = 0; j < 3; j++) {
            if ((i == bi) && (j == bj)) {
                continue Z;
            }

            else if (m[i][j] == n) {
                n++;
            }

            else {
                this.getSolutionIndex();
                mh = mh + Math.abs(i - si) + Math.abs(j - sj);
            }

        }
}

void getSolutionIndex() {
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++) {
            if (m[i][j] == 0) {
                si = i;
                sj = j;
            }
        }

}

public Iterable<State> neighbours()
{
    tempm = m;
    this.up();
    if(!(equals(tempm)))
    {
        tempState = new State(this,count,tempm);
        neighbourStates.add(tempState);
    }

    this.down();
    if(!(equals(tempm)))
    {
        tempState = new State(this,count,tempm);
        neighbourStates.add(tempState);
    }

    this.left();
    if(!(equals(tempm)))
    {
        tempState = new State(this,count,tempm);
        neighbourStates.add(tempState);
    }

    this.right();
    if(!(equals(tempm)))
    {
        tempState = new State(this,count,tempm);
        neighbourStates.add(tempState);
    }

    return neighbourStates;     

}

public boolean equals(int s[][])
{
    if((isInitialState==false)&&(previousState.m == s))
        return true;
    else
        return false;

}

@Override
public Iterator<State> iterator() {
    // TODO Auto-generated method stub
    return null;
}

public void up()
{
    if ((bi > 1) && (bi < 2) && (bj < 3)&& (bj > 1))
    {
        i = bi;
        i = i + 1;
        this.move(i,bj);
    }

}

public void  down()
{
    if ((bi > 2) && (bi < 3) && (bj < 3) && (bj > 1)) 
    {
        i = bi;
        i = i - 1;
        this.move(i,bj);
    }
}

public void left()
{
    if ((bi > 1) && (bi < 3) && (bj < 2)&& (bj > 1)) {
        j = bj;
        j = j + 1;
        this.move(bi, j);
    }
}

public void right()
{
    if ((bi > 1) && (bi < 3) && (bj < 3) && (bj > 2)) {
        j = bj;
        j = j - 1;
        this.move(bi, j);

    }

}

public void move(int x, int y) {
    {
        tempm = m;
    }
    if ((tempm[x + 1][y] == 0) || (tempm[x - 1][y] == 0) || (tempm[x][y + 1] == 0)|| (tempm[x][y - 1] == 0)) {
        tempm[bi][bj] = tempm[x][y];
        tempm[x][y] = 0;
        bi = x;
        bj = y;



    }
}

}

最后是具有主要功能的类。

  import java.util.Scanner;
  public class Main {
  public static void main(String[] args) 
  {
     @SuppressWarnings("resource")
     Scanner sc = new Scanner(System.in);
     int[][] tiles = new int[3][3];
     System.out.println("Enter the elements");
     for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            tiles[i][j] = sc.nextInt();
     State initial = new State(null,0,tiles);
     Solver solver = new Solver(initial);
     solver.solution();

     System.out.println("Minimum number of moves = " + solver.moves());

     }

}

我不明白的是,当我明确声明它为16时,ArrayList的大小如何为1。

您没有将ArrayList的大小设置为16。您已经设置了容量:

queue.ensureCapacity(16);
solQueue.ensureCapacity(16);

这不会使ArrayList的大小为16。

ArrayList有一个数组来保存其数据。 当您向ArrayList添加更多元素并且其内部数组已满时,它将必须分配一个更大的数组,并复制当前持有的内容以及新元素。

ArrayList容量是内部阵列的最小大小。 您可以使用ensureCapacity来确保ArrayList不必经常调整大小(调整大小和复制内容是一项昂贵的操作)。 所以, ensureCapacity是你让使它effiently工作的电话。

它不会使ArrayList具有16个元素; 它仅确保ArrayList至少可容纳16个元素。

如果希望ArrayList具有16个元素,则必须一个一个地添加这些元素。

集合的大小和容量是2个不同的概念。

  • 容量表示集合无需重新分配即可容纳的最大项目大小。
  • size表示集合中当前的项目数。

IndexOutOfBoundsException表示您正在尝试访问具有集合中不存在的索引的项目。

请在Solver.java中尝试以下代码

if(!queue.isEmpty())removeTemp = queue.remove(removeIndex); 否则休息;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM