1

I've just started to learn Java,and I've got some questions for my code. Well,the task is to get a number and print a matrix like this:

get 3,and print:
    1 2 3
    8 9 4
    7 6 5

get 4,and print:
    1  2  3  4
    12 13 14 5
    11 16 15 6
    10 9  8  7

Because I'm learning algorithm,so I deal the question by DFS, here's my cpp code,which can solve the task.

#include "iostream"
using namespace std;
int n;
int matrix[100][100]={0};
int visited[100][100]={0};


void dfs(int n,int x,int y,int i,int dire)
{
//x,y is the coordinate,i is the number to write
//dire is the variety to control the direction of the dfs
    if(i==n*n+1)return;
    switch(dire)
    {
        case(1)://write the number on right
        {
            if(visited[x][y+1]==0&&y+1<n)
            {
                visited[x][y+1]=1;
                matrix[x][y+1]=i;
                i++;
                dfs(n,x,y+1,i,1);
            }
            else dfs(n,x,y,i,2);
            break;
        }
        case(2)://down
        {
            if(visited[x+1][y]==0&&x+1<n)
            {
                visited[x+1][y]=1;
                matrix[x+1][y]=i;
                i++;
                dfs(n,x+1,y,i,2);
            }
            else dfs(n,x,y,i,3);
            break;
        }
        case(3)://left
        {
            if(visited[x][y-1]==0&&y-1>=0)
            {
                visited[x][y-1]=1;
                matrix[x][y-1]=i;
                i++;
                dfs(n,x,y-1,i,3);
            }
            else dfs(n,x,y,i,4);
            break;
        }
        case(4)://up
        {
            if(visited[x-1][y]==0&&x-1>=0)
            {
                visited[x-1][y]=1;
                matrix[x-1][y]=i;
                i++;
                dfs(n,x-1,y,i,4);
            }
            else dfs(n,x,y,i,1);
            break;
        }
    }
}

 void output(int n)
{
    int p,q=0;
    for(q=0;q<n;q++)
    {
        for(p=0;p<n;p++)
        {
            cout<<matrix[q][p]<<" ";
            if(matrix[q][p]<10)
                cout<<" ";
            if(matrix[q][p]<100)
                cout<<" ";
        }
        cout<<endl;
    }
}
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            matrix[i][j]=0;
            visited[i][j]=0;
        }
    }
    ///dfs_r(n,0,-1,1);
    dfs(n,0,-1,1,1);
    output(n);
}

But things goes wrong when I translate it into Java

import java.util.Scanner;
public class mainclass{
    public static class method{
        int n;
        int visited[][]=new int[n][n];
        int matrix[][]=new int[n][n];
        method(int temp){
            n=temp;
        }
        void dfs(int x,int y,int i,int dire)
        {
            if(i==n*n+1)return;
            switch(dire)
            {
                case(1):
                {
                    if(visited[x][y+1]==0&&y+1<n)
                    {
                        visited[x][y+1]=1;
                        matrix[x][y+1]=i;
                        i++;
                        dfs(x,y+1,i,1);
                    }
                    else dfs(x,y,i,2);
                    break;
                }
                case(2):
                {
                    if(visited[x+1][y]==0&&x+1<n)
                    {
                        visited[x+1][y]=1;
                        matrix[x+1][y]=i;
                        i++;
                        dfs(x+1,y,i,2);
                    }
                    else dfs(x,y,i,3);
                    break;
                }
                case(3):
                {
                    if(visited[x][y-1]==0&&y-1>=0)
                    {
                        visited[x][y-1]=1;
                        matrix[x][y-1]=i;
                        i++;
                        dfs(x,y-1,i,3);
                    }
                    else dfs(x,y,i,4);
                    break;
                }
                case(4):
                {
                    if(visited[x-1][y]==0&&x-1>=0)
                    {
                        visited[x-1][y]=1;
                        matrix[x-1][y]=i;
                        i++;
                        dfs(x-1,y,i,4);
                    }
                    else dfs(x,y,i,1);
                    break;
                }
            }
        }
        void output()
        {
            int p,q=0;
            for(q=0;q<n;q++)
            {
                for(p=0;p<n;p++)
                {
                    System.out.print(matrix[q][p]);
                    if(matrix[q][p]<10)
                        System.out.print(" ");
                    if(matrix[q][p]<100)
                        System.out.print(" ");
                }
                System.out.println();
            }
        }
    }

    public static void main(String args[]){
        Scanner reader=new Scanner(System.in);
        int n=reader.nextInt();
        method c=new method(n);
        c.dfs(0,-1,1,1);
        c.output();
    }
}

I think my algorithm is all right,but I can't work it out why my Java code crashes. I think I should learn more about basic grammar of Java.

edit: I use dev-cpp to run my cpp code and eclipse to run my Java code. I'm not really know how to describe how does the crash of my Eclipse got, the code is:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0

at mainclass$method.dfs(mainclass.java:17)

at mainclass.main(mainclass.java:87)


<terminated, exit value: 1>C:\Program Files\Java\jre1.8.0_101\bin\javaw.exe (2016年9月27日 上午9:51:32)  

the crash scene

6
  • Because your C++ code is working (at least according to you), you might be better off posting this on Code Review. Commented Sep 27, 2016 at 1:42
  • 1
    what is the nature of the crash? Commented Sep 27, 2016 at 1:42
  • I am guess you are getting an out of bounds exception, so try swapping the order of if(visited[x][y+1]==0&&y+1<n) to if(y+1<n && visited[x][y+1]==0) Commented Sep 27, 2016 at 1:44
  • java class names should start with a capital letter and the brackets should start on the same line Commented Sep 27, 2016 at 8:00
  • This exception means that you are trying to get a value from an index that is not present in your array; For example, when you do array[2] (effectively third item, including 0 index), but your array only has two items, indexed 0 and 1. The easiest thing would be to use some modern IDE, place a breakpoint on the line where you get the exception and debug it step by step to check what happens. Commented Sep 27, 2016 at 8:20

1 Answer 1

1

(The answer there supposes you have an IDE, like Eclipse).

The really, really dirty way

You can, when in doubt, always rely on a good old System.out.println(yourobject). Be careful about objects, never forget that you can turn them into String and check inner objets (in your case, visited[1][2] or matrix[2][0] for example). BUT it sucks. Really. It might suffice for your needs, but it is really a bad habit to take.

The 'okay' way (EDIT)

Use a tool named SLF4J to get some additional traces. As you are only on a small method and not a complete project, I would not command you to deploy this tool yet, but keep in mind that it is a good way to both figure out what happens and have your console logging what you need, especially when the projects are getting intersting (read: bigger).

The good and elegant way

Learn a bit about a tool called debug mode. You can find further help on the Eclipse help center, but basically the steps are:

  • Place a breakpoint. On the left of your code (with line numbers), you can right-click to toogle / enable / disable breakpoints.
  • Run your program in debug. It is a little bug (how convenient) near the classic run icon. You'll get redirected to the debug perspective.
  • The run will be interrupted where you toogled your breakpoint. There, you will be able to go, step by step, into your code. You will also be able to check the state of every variable you declared, in order to identify your problem.
  • [Your job here is to make the necessary changes]
  • Now you know about debugger, ArrayOutOfBoundsException and became a better person in general thanks to this good practice.

Vogella has a good tutorial about how to use the debugger in a nice way. Learn to use it if you plan on keeping on Java, because this will save you a lot of time (an awful lot, believe me).

Sign up to request clarification or add additional context in comments.

2 Comments

I don't really agree that using System.out.println is a dirty way, there is a reason msot loggers have multiple level, including "debug". Here he might find out which values for the the function "dfs" generates the exception. Of course I agree, the debug mode is a really powerfull tool and knowing how to use it is really valuable (but complementary to using logging).
If you plan on using logging, you should rely on tools like SLF4J to get a clearer view. Using System.out.println takes you an awful time setting it up and removing it. And debug mode can provide you with information about your variables anyway, there is no point printing the variable where he can provide you an overview of all of them, inside your method or globally.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.