尽管使用了 indexInBounds,但仍获得 ArrayIndexOutOfBounds

Posted

技术标签:

【中文标题】尽管使用了 indexInBounds,但仍获得 ArrayIndexOutOfBounds【英文标题】:Getting ArrayIndexOutOfBounds despite using indexInBounds 【发布时间】:2014-02-24 19:10:32 【问题描述】:

检查和保持程序入站的方法是否不起作用我不断收到:array IndexOutOfBounds error。由于这个错误,我无法继续查看我的 Knight's Tour 的实际实施是否有效。

import java.util.Arrays;
class KnightsTour 

    static int the_board[][] = new int[8][8];
    int the_tour[][] = new int [8][8];
    int k,moves = 0;
    int x = 0, y = 0; 
    int z, j = 1;
    boolean tour_found, isSafe;

        //fills 2D array with 0's
        public KnightsTour()
        
            for (int i = 0; i < 8; i++) 
                
                 for (int r = 0; r < 8; r++) 
                    
                            the_board[i][r] = 0;
                        
                
        
        /*recursive method, checks how many moves were made if 16 were made tour finished, 
        else if not moves knight checks if the move is valid if not back tracks*/
        public void findTour(int q)
        
            if(moves == 68)
                
                    tour_found = true;
                

            else move(q); 
            if(isSafe == true)
                    
                        findTour(q++);
                        moves++;
                    
            else
                if(isSafe == false)
                    
                        findTour(q*(-1));
                        moves--;
                    
        
        //used to keep prevent arrayindexoutofbounds error
        public boolean arrayInBounds(int x, int y)
         
        if(x > 8 || y > 8)
                
                    return false;
                
            else return true;
        
        /*move method uses switch statement to decide which move the knight should make
        based on a case number, negative case numbers back track knight. if statement checks
        if the current array element is empty and the index is inbounds*/
        public void move(int a)
        

            switch (a)
            
               case 1:
                if(arrayInBounds(x+2, y+1) == true)
                   if(the_board[x+2][y+1] != 0)                          
                        the_board[x+2][y+1]=j;
                            j++;
                        
                    
                else isSafe = false;
               case 2:
                if (arrayInBounds(x+1, y+2) == true)
                    if(the_board[x+1][y+2] != 0)               
                            the_board[x+1][y+2]=j;
                            j++;
                        
                
                else isSafe = false;
               case 3:
                 if(arrayInBounds(x-1, y+2) == true)
                   if(the_board[x-1][y+2] != 0)           
                            the_board[x-1][y+2]=j;
                            j++;
                        
                 
                else isSafe = false;
               case 4:
                if (arrayInBounds(x-2, y+1) == true)
                    if(the_board[x-2][y+1] != 0)           
                            the_board[x-2][y+1]=j;
                            j++;
                        
                
                else isSafe = false;
               case 5:
                if(arrayInBounds(x-2, y-1) == true)
                    if(the_board[x-2][y-1] != 0)           
                            the_board[x-2][y-1]=j;
                            j++;
                        
                
                else isSafe = false;
               case 6:
                if(arrayInBounds(x-1, y-2) == true)
                        if(the_board[x-1][y-2] != 0)                    
                            the_board[x-1][y-2]=j;
                            j++;
                        
            
                else isSafe = false;
               case 7:
                 if(arrayInBounds(x+1, y-2) == true)
                    if(the_board[x+1][y-2] != 0)          
                            the_board[x+1][y-2]=j;
                            j++;
                        
                 
                 else isSafe = false;
               case 8:
                if(arrayInBounds(x+2, y-1) == true)
                 if(the_board[x+2][y-1] != 0)
                            the_board[x+2][y-1]=j;
                            j++;
                        
                
                else isSafe = false;
               case -1:
                 the_board[x-2][y-1]=0;
                      j--;
               case -2:
                 the_board[x-1][y-2]=0;
                      j--;
               case -3:
                 the_board[x+1][y-2]=0;
                      j--;
               case -4:
                 the_board[x+2][y-1]=0;
                      j--;
              case -5:
                 the_board[x+2][y+1]=0;
                      j--;
               case -6:
                 the_board[x+1][y+2]=0;
                      j--;
               case -7:
                 the_board[x-1][y+2]=0;
                      j--;
               case -8:
                 the_board[x-2][y+1]=0;
                      j--;
                

        
        //for loop to display tour once found//         
        public void displayTour()
        
            int v = 1;
            for (int i = 0; i < 8; i++) 
                
                 for (int e = 0; e < 8; e++) 
                                   
                                if(v % 8 == 0)
                                
                                    System.out.print(the_board[i][e] + "\t");
                                    System.out.println("\n");
                                 
                        else    
                            System.out.print(the_board[i][e] + "\t");
                            v++;                
                        
                

        


【问题讨论】:

【参考方案1】:

您的arrayInBounds 方法不正确。 8 是无效索引,但您的方法会错误地将其报告为有效。此外,它不会检查0 以下的无效索引。

更改您的方法以检查xy 是否大于或等于 8,并检查是否小于0

【讨论】:

如果我可以添加一个样式建议,if a return false else return true 是一个糟糕的反模式。使用return !a【参考方案2】:

你的棋盘是一个二维数组,8 x 8。但是,由于数组的索引是从 0 开始的,所以你的棋盘看起来像这样:

00 10 20 30 40 50 60 70 01 11 21 31 41 51 61 71 02 12 22 32 42 52 62 72 03 13 23 33 43 54 63 73 04 14 24 34 44 54 64 74 05 15 25 35 45 55 65 75 06 16 26 36 46 56 66 76 07 17 27 37 47 57 67 77

因此,如果您允许值为 8 的 indeces,它们实际上将位于 第 9 位,因此超出范围。

所以,要查看一个数组是否超出范围,要么检查索引是否大于或等于 8,要么检查它是否大于7.

或者,切换你的逻辑,以便检查它是否是界内,而不是界外。所以我建议改变你的方法:

public boolean arrayInBounds(int x, int y)  
    if(x > 8 || y > 8) 
        return false;
     else 
        return true;
    

到这里:

public boolean arrayInBounds(int x, int y) 
    return (x < 8 && y < 8 && x >= 0 && y >= 0);

【讨论】:

感谢成功!!现在我已经解决了这个问题,我在运行程序时收到了堆栈溢出错误。知道那可能是什么吗? @user2612136 听起来你在某处有无限递归(一种方法调用自身而无法中断),或者可能是无限循环。在堆栈跟踪中查看它告诉您出错的行。这应该让你知道它在做什么。 @user2612136 另外,它可能被扔到了 KnightsTour 以外的其他类别中。您可能应该在单独的问题中询问堆栈溢出错误。 (然后在评论中链接到它,这样我就可以找到它并检查它。)当然,除非你自己解决它(这应该不难)。

以上是关于尽管使用了 indexInBounds,但仍获得 ArrayIndexOutOfBounds的主要内容,如果未能解决你的问题,请参考以下文章

尽管在数据帧上使用 .loc 方法,但仍获得 SettingWithCopyWarning [重复]

尽管使用了过滤器,但仍被 CORS 策略阻止

尽管更改了progressDeadlineSeconds,但仍会遇到“超过进度期限”

尽管在画面中进行过滤,但仍应用参数控制

函数调用报告尽管传递了有效参数,但仍给出了 0 个参数

尽管启用了本机代码调试,但仍无法从托管调试本机代码