问题
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?
回答1:
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);
来源:https://stackoverflow.com/questions/31631249/avoiding-duplicates-in-adjacency-linked-list-graph