避免邻接链接列表图中的重复

时间:2015-07-25 21:20:05

标签: java graph adjacency-list

这是我在这里发表的第一篇文章

我环顾四周,找不到一个特定的问题,这个问题已经足够让我能够理解并实施我自己的解决方案了。我找到了大约3个关于类似项目的链接,但没有相对接近相同的实现或问题。

我使用Hashmap将键存储为字符串,将值存储为顶点,顶点保持其邻接列表本身,以避免在hashmap中重复执行查找。

是的,这是家庭作业,我已经尝试了几天,只是简单地从文件创建一个图表,但似乎无法完全正确。我的图表的两个方向都正常工作,因此它是无向的,但我似乎无法避免重复

请原谅凌乱的代码,这些对象抛出了很多例外,我就是抓住每一个人的类型大声笑。

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();
    }

此代码的输出是

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

你在这里看到的第一个城市是“消息来源”,列表中的其他城市将成为来源城市能够前往的“目的地”。

例如,这两行是在我的文件中

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

如您所见,输出在这里:

 DFW|  BOS MOB HOU ATL ATL AUS SAT SFO LAX

在列表中显示ATL两次,在检查我提供的2行时,您可以看到它是因为ATL转到DFW并且DFW也转到ATL,但我也已经到达目的地指向的位置在源头发生两次。我的if语句并没有阻止这种情况发生。还有其他问题吗?我可以简单地使用Set吗?

1 个答案:

答案 0 :(得分:0)

愚蠢的我......我只需要另外一个if语句

这里我应该说这个

/* 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);