简体   繁体   中英

using a list of lists in java

I'm writing a code that should theoretically take a text file representation of a graph with a number of vertices, edges, and a list of edges, and use depth-first-search to determine if it's bipartite. However I'm using an Arraylist of lists to store the adjacency lists, and I keep getting java.lang.IndexOutOfBoundsException: Index: 1, Size: 0 error at the for loop in the childColor method

import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.*;
import static java.lang.System.*;
import java.util.*;

public class detect_bipartite {
    public static void main(String[] args){
        int bipartCheck = 1;
        List<Integer> numList = new ArrayList<Integer>();   
        File inFile = null;
        //separate white space
        if (0 < args.length) {
            inFile = new File(args[0]);
        }        

        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(inFile));
            String text = null;

            while ((text = reader.readLine()) != null) {
                String[] tmp = text.split(" ");
                for(String str: tmp)
                    if(!str.equals("")){
                        numList.add(Integer.parseInt(str));}

            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
            }
        }

        int n = numList.get(0);
        int m = numList.get(1);

        List<Integer> edgeA = new ArrayList<Integer>();
        List<Integer> edgeB = new ArrayList<Integer>();

        for(int i=2; i<numList.size(); i++){
            if(i%2==0){edgeA.add(numList.get(i));}
            else if(i%2==1){edgeB.add(numList.get(i));}
        }

        List<List<Integer>> adjLists = new ArrayList<List<Integer>>(n);
        for(int j = 1; j <= adjLists.size(); j++){      //get adjacency lists
            for(int a=1; a <=edgeA.size(); a++){
                if(edgeA.get(a)==j){ (adjLists.get(j)).add(edgeB.get(a));}
                if(edgeB.get(a)==j){ (adjLists.get(j)).add(edgeA.get(a));}
            }
        }

        int[] color = new int[n];
        Arrays.fill(color, 0);
        //0 = uncolored
        //1 = red
        //2 = blue

        int bipart = childColor(n, 1, adjLists, color, 1);
        if (bipart==0){bipartCheck = 0;}

        for(int d = 0; d < n; d++)      //for any disconnected graphs
        {
            if(color[d] == 0){
                bipart = childColor(n, d, adjLists, color, 1);}
            if (bipart==0){bipartCheck = 0;}
        }


        if(bipartCheck == 1){
            System.out.println("Bipartite");
        } else{
            System.out.println("Not a Bipartite");
        }
    }

    public static int childColor(int n, int node, List<List<Integer>> adjLists, int[] color, int nodeColor){
        if(color[node] == nodeColor){
            return 1;}
        int bipart = 1;
        int newColor;
        if(nodeColor == 1){newColor = 2;}
        else{newColor = 1;}
        if(color[node] == newColor)
        {return 0;}
        color[node] = nodeColor;
        for(int k = 0; k < adjLists.get(node).size(); k++){  **//This is the error line**
            bipart = childColor(n, adjLists.get(node).get(k), adjLists, color, newColor);
            if(bipart == 0)
            {return 0;}
        }

        return bipart;
    }
}

When you do:

List<List<Integer>> adjLists = new ArrayList<List<Integer>>(n);

You create an ArrayList with initial capacity n . This does not mean the list has size n though . In fact, since the list has no elements, its size is 0. Given that, 1 <= 0 is false and this loop is never executed:

for(int j = 1; j <= adjLists.size(); j++){      //get adjacency lists
    for(int a=1; a <=edgeA.size(); a++){
        if(edgeA.get(a)==j){ (adjLists.get(j)).add(edgeB.get(a));}
        if(edgeB.get(a)==j){ (adjLists.get(j)).add(edgeA.get(a));}
    }
}

So, when you call childColor(n, 1, adjLists, color, 1) , adjLists is empty . When you try to access an element at index 1, by doing adjLists.get(node) , there is no element, thus the IndexOutOfBoundsException .

Also note that Java lists and arrays indices start at 0, not 1.

To solve the problem, you could initialize all the lists before trying to use them:

List<List<Integer>> adjLists = new ArrayList<List<Integer>>(n);
for (int i = 0; i < n; i++) {
    adjLists.add(new ArrayList<>());
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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