简体   繁体   中英

Avoiding Duplicates in Adjacency Linked List Graph

this is my first post here

I have looked around and could not find a particular question that is having a problem close enough to mine for me to be able to understand and implement a solution of my own. I found about 3 links that were about a similar project, but not relatively close to the same implementation or problem.

I am using a Hashmap that stores keys as strings and values as vertices, with the vertices holding their adjacency lists themselves in order to avoid having to repeatedly do a lookup in the hashmap.

Yes, this is homework and I have tried for days to just simply create a graph from a file and just cant seem to quite get it right. I have both directions of my graph working correctly, so it is undirected, but I cannot seem to avoid duplicates

please excuse the messy code, these objects throw lots of exceptions and I am the type of person to catch every one of them lol.

public AirportGraph(File file)
    {
        this.airports = new HashMap(DEFAULT_SIZE, DEFAULT_LOAD);
        processFile(file);
    }

    private void processFile(File file)
    {   
        Scanner sc;

        /* First we must try to create a scanner from the file */
        try 
        {
            sc = new Scanner(file);

            /* Initializing the hashmap with empty lists in this loop */
            while (sc.hasNext())
            {
                String from = new String();

                /* Here we are skipping over integers for now */
                try
                {
                    from = sc.next();
                    Integer.parseInt(from);
                }
                /* If parsing the int failed, it must be an airport id */
                catch(NumberFormatException e)
                {
                    /* Make sure it does not already contain the key in the hashmap */
                    if (this.airports.containsKey(from))
                        continue;

                    /* Add the key and value to the hashmap */
                    AirportVertex source = new AirportVertex(from);
                    airports.put(from, source);
                    this.numNodes++;
                }
                catch(NoSuchElementException e)
                {
                    System.err.println("There are no more tokens available");
                    e.printStackTrace();
                }
                catch(IllegalStateException e)
                {
                    System.err.println("The scanner is closed");
                    e.printStackTrace();
                }
            }

            /* Reinitialize the scanner */
            sc = new Scanner(file);

            /* Adding adjacent airports */
            while(sc.hasNextLine())
            {
                String line = new String();

                /* Try to create Scanner for the line read from the file */
                try
                {
                    line = sc.nextLine();
                    Scanner tokens = new Scanner(line);

                    /* Try to read tokens */
                    try
                    {
                        String from = tokens.next();


                        /* The first token is the source airport */
                        AirportVertex source = this.airports.get(from);

                        /* The file has a pattern of alternating strings and ints after the first string read on each line */
                        AirportVertex dest = this.airports.get(tokens.next());
                        source.adj_lst.add(dest);

                        /* Read the rest of the line */
                        while (tokens.hasNext())
                        {
                            int cost = tokens.nextInt();

                            AirportVertex nextDest = this.airports.get(tokens.next());

                            if (!dest.adj_lst.contains(nextDest))
                                dest.adj_lst.add(nextDest);

                            if(!nextDest.adj_lst.contains(dest))
                                nextDest.adj_lst.add(dest);

                            dest = nextDest;
                        }
                    }
                    catch(NoSuchElementException e)
                    {
                        System.err.println("There are no more tokens available to scan for the ");
                    }
                    catch(IllegalStateException e)
                    {
                        System.err.println("The scanner is closed");
                        e.printStackTrace();
                    }
                }
                catch(NoSuchElementException e)
                {
                    System.err.println("No line could be found");
                }
                catch(IllegalStateException e)
                {
                    System.err.println("The scanner is closed");
                    e.printStackTrace();
                }
            }
        } 
        catch (FileNotFoundException e) 
        {
            System.err.println("File could not be found");
            e.printStackTrace();
        }

        print();
    }

The output of this code is

SHV|  OKC SFO DFW
MOB|  DFW ATL
LAX|  HOU LIT DFW
OKC|  MSY SHV DFW
BOS|  DFW ATL AUS HOU
SAT|  HOU DFW AUS
HOU|  DFW SAT BOS LAX AUS
MSY|  LIT OKC DFW
DFW|  BOS MOB HOU ATL ATL AUS SAT SFO LAX
LIT|  LAX MSY DFW
ATL|  BOS DFW AUS
SFO|  SHV DFW DFW
AUS|  DFW ATL BOS HOU

The first city you see here is the "SOURCE" and the rest of the cities in the list are to be the "DESTINATIONS" that the source city is able to go to.

These 2 lines, for example, are in my file

BOS  ATL 250  DFW 250 
DFW  ATL 250  AUS 59  BOS 250  HOU 128  LAX 1000  LIT 59  MSY 128  OKC 59  SHV 59  SFO 1200

As you can see, the output Here:

 DFW|  BOS MOB HOU ATL ATL AUS SAT SFO LAX

is showing ATL twice in the list, which when examining the the 2 lines i provided, you can see it is because ATL goes TO DFW and DFW also goes TO ATL, but I have also made it to where the destination points back at the source which happens twice. My if statements are not stopping this from happening. Is there something else going wrong??? Could I simply just use a Set?

Silly me... I only needed one other if statement

Here I should have said this instead

/* The first token is the source airport */
AirportVertex source = this.airports.get(from);

/* The file has a pattern of alternating strings and ints after the first string read on each line */
AirportVertex dest = this.airports.get(tokens.next());

if (!source.adj_lst.contains(dest))
    source.adj_lst.add(dest);

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