0

0

Java航班网络中转连接与总距离计算教程

花韻仙語

花韻仙語

发布时间:2025-11-23 15:20:16

|

233人浏览过

|

来源于php中文网

原创

Java航班网络中转连接与总距离计算教程

本教程详细讲解如何在java中实现一个航班路径可视化程序,重点解决如何根据用户提供的中转城市,准确显示该中转城市的所有直接连接及其到最终目的地的总距离。我们将通过优化图遍历逻辑和距离计算方法,确保程序能够正确地筛选并展示从起始城市经中转城市到达目的地的完整路径及累计里程。

引言:构建航班网络可视化系统

在航空领域,航班路径的可视化和距离计算是常见的需求。通过图数据结构,我们可以高效地表示城市(节点)和航班线路(边),并附加距离信息(边的权重)。本教程将指导您如何在一个已有的Java航班网络程序中,实现一个功能,即当用户指定一个中转城市后,程序能够准确地列出从该中转城市出发的所有直接连接,并计算从起始城市到这些最终目的地的总距离。

理解现有航班图结构

在深入解决问题之前,我们先回顾一下当前程序中使用的核心类和数据结构:

  1. Vertex.java:

    • 表示图中的一个节点(城市)以及从其“父节点”到自身的权重(距离)。
    • label: 城市名称(字符串)。
    • weight: 到达该城市的距离(整数)。
    public class Vertex {
        String label;
        int weight;
        public Vertex(String label, int weight) {
            this.label = label;
            this.weight = weight;
        }
    }
  2. HWGraph.java:

    立即学习Java免费学习笔记(深入)”;

    • 表示整个航班网络图,采用邻接表(Adjacency List)的形式存储。
    • graphMap: HashMap<String, ArrayList<Vertex>>,其中键是城市名称(字符串),值是该城市所有直接连接的Vertex对象列表。每个Vertex对象代表一个可达的城市及其与当前城市的距离。
    • addVertex(String label): 添加一个城市到图中。
    • addEdge(String label1, Vertex v): 添加一条从label1到v.label的边,距离为v.weight。
    • getConnections(String label): 获取指定城市的所有直接连接。
    • getThisVertex(String startCity, String destCity): 在startCity的连接中查找destCity对应的Vertex对象,用于获取从startCity到destCity的距离。
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Set;
    
    public class HWGraph {
        public HashMap<String, ArrayList<Vertex>> graphMap = new HashMap<>();
    
        public void addVertex( String label ){
            ArrayList<Vertex> items = new ArrayList<>();
            graphMap.put( label, items);
        }
        // ... (其他方法省略) ...
        ArrayList<Vertex> getConnections( String label){
            return graphMap.get(label);
        }
        Vertex getThisVertex( String startCity, String destCity){
            ArrayList<Vertex> destCities = this.getConnections( startCity);
            for( Vertex v : destCities){
                if ( v.label.equalsIgnoreCase(destCity)){
                    return v;
                }
            }
            return null;
        }
    }

识别并解决核心问题

原始代码中的showConnections方法存在两个主要问题:

  1. 遍历范围不准确: showConnections方法通过g.graphMap.forEach((key, value) -> connect(key, value));遍历了整个图的所有连接,而不是仅仅显示用户指定中转城市的后续连接。
  2. 距离计算不完整: connect方法只打印了单段距离,没有将从起始城市到中转城市的距离考虑在内,以计算总距离。

为了解决这些问题,我们需要对HWDriverPrep.java中的showConnections方法及其调用逻辑进行重构。

Bolt.new
Bolt.new

Bolt.new是一个免费的AI全栈开发工具

下载

优化连接显示逻辑

我们将修改showConnections方法,使其能够:

  1. 只关注特定中转城市的连接。
  2. 接收从起始城市到中转城市的累计距离。
  3. 计算并显示从起始城市经中转城市到最终目的地的总距离。

1. 重构 showConnections 方法

首先,我们将移除原showConnections中遍历整个graphMap的逻辑,并引入新的参数来传递中转城市的名称和从起始城市到中转城市的距离。

// HWDriverPrep.java
// ... (其他不变的代码) ...

private static void showConnections(HWGraph g, String layOverCityLabel, int distanceToLayover) {
    // 1. 获取中转城市的所有直接连接
    ArrayList<Vertex> connections = g.getConnections(layOverCityLabel);

    // 2. 处理无后续连接的情况
    if (connections == null || connections.isEmpty()) {
        System.out.printf("  城市 %s 无后续连接。\n", layOverCityLabel);
        return;
    }

    // 3. 打印中转城市信息
    System.out.printf("  从 %s (起始到中转总距离: %d) 出发,后续连接如下:\n", layOverCityLabel, distanceToLayover);

    // 4. 遍历并打印每个后续连接及其总距离
    for (Vertex destination : connections) {
        int totalDistance = distanceToLayover + destination.weight; // 计算总距离
        System.out.printf("    -> 目的地: %s, 段距离: %d, 总距离: %d\n",
                          destination.label, destination.weight, totalDistance);
    }
}

// 原有的 connect 方法不再需要,因为其功能已被整合到 showConnections 中
// private static void connect(String key, ArrayList<Vertex> value) { ... }

2. 更新 main 方法中的调用

在main方法中,我们需要确保在调用showConnections时,传入正确的参数:中转城市的名称和从起始城市到中转城市的距离。

// HWDriverPrep.java
import java.util.ArrayList;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

public class HWDriverPrep {
    public static void main(String[] args) {
        HWGraph g = createGraph();
        // printGraph( g ); // 可选:如果不需要打印整个图的连接,可以注释掉

        Set<String> keys = g.getKeys();
        String startCity = "Chicago"; // 示例起始城市

        // 获取用户输入的中转城市
        String layOver = getLayOverCity( keys, startCity);

        // 获取从起始城市到中转城市的Vertex对象。
        // 这个Vertex对象的label是中转城市名,weight是从startCity到layOver的距离。
        Vertex layOverVertexFromStart = g.getThisVertex(startCity, layOver);

        if (layOverVertexFromStart == null) {
            System.out.println("\n错误:指定的中转城市不存在或无法从起始城市直接到达。");
            return;
        }

        System.out.printf("\n 从起始城市:%s 到中转城市:%s 的距离为: %d\n",
                          startCity, layOverVertexFromStart.label, layOverVertexFromStart.weight);
        System.out.printf(" 中转城市 %s 的后续连接及总距离:\n", layOverVertexFromStart.label);

        // 调用修改后的 showConnections 方法,传入中转城市名称和从起始城市到中转城市的距离
        showConnections(g, layOverVertexFromStart.label, layOverVertexFromStart.weight);
    }

    // ... (createGraph, printGraph, show, getLayOverCity 等其他方法不变) ...

    // printGraph 方法可以保留,用于调试或显示整个图的结构
    private static void printGraph(HWGraph g) {
        g.graphMap.forEach(
                (key,value) -> show(key,value));
    }
    private static void show(String key, ArrayList<Vertex> value) {
        System.out.println("Showing connections for key: " + key + "--------");
        for(Vertex v : value){
            System.out.println("City: " + v.label + " Distance: " + v.weight);
        }
    }
    private static String getLayOverCity(Set<String> keys, String startCity) {
        // ... (此方法保持不变) ...
        String oStr = "";
        String cm = "";
        for(String item: keys)
        {
            oStr += cm + item;
            cm = ", ";
        }
        System.out.printf("Select a layover City(%s): ",oStr); // 改进提示信息
        Scanner s = new Scanner(System.in);
        String retItem = s.nextLine();
        return retItem;
    }

    // createGraph 方法保持不变
    private static HWGraph createGraph() {
        HWGraph g = new HWGraph();
        g.addVertex("Chicago");
        g.addVertex("Dallas");
        g.addVertex("Atlanta");
        g.addVertex("New York");
        g.addVertex("Houston");
        g.addVertex("Orlando");

        // --- now add connections
        g.addEdge("Chicago",new Vertex("Dallas",968));
        g.addEdge("Chicago",new Vertex("Atlanta",718));
        g.addEdge("Chicago",new Vertex("New York",790));

        g.addEdge("Dallas",new Vertex("Houston",239));
        g.addEdge("Dallas", new Vertex("Orlando",1120));

        g.addEdge("Houston", new Vertex("Orlando",967));

        g.addEdge("Atlanta", new Vertex("Dallas",781));
        g.addEdge("Atlanta", new Vertex("New York",870));
        g.addEdge("Atlanta", new Vertex("Orlando",438));

        g.addEdge("New York", new Vertex("Houston",1647));
        g.addEdge("New York", new Vertex("Orlando",1080));

        return g;
    }
}

示例运行与输出

假设起始城市为 Chicago,用户输入中转城市为 New York。

  1. getThisVertex("Chicago", "New York") 将返回一个 Vertex("New York", 790) 对象,表示从芝加哥到纽约的距离是790。
  2. showConnections 方法将被调用为 showConnections(g, "New York", 790)。
  3. showConnections 内部会调用 g.getConnections("New York"),这将返回 [Vertex("Houston", 1647), Vertex("Orlando", 1080)]。
  4. 程序将遍历这些连接并计算总距离:
    • 对于 Houston: 总距离 = 790 (Chicago->NY) + 1647 (NY->Houston) = 2437。
    • 对于 Orlando: 总距离 = 790 (Chicago->NY) + 1080 (NY->Orlando) = 1870。

最终输出将类似于:

Select a layover City(Chicago, Dallas, Atlanta, New York, Houston, Orlando): New York

 从起始城市:Chicago 到中转城市:New York 的距离为: 790
 中转城市 New York 的后续连接及总距离:
   从 New York (起始到中转总距离: 790) 出发,后续连接如下:
     -> 目的地: Houston, 段距离: 1647, 总距离: 2437
     -> 目的地: Orlando, 段距离: 1080, 总距离: 1870

注意事项与最佳实践

  • 参数的有效利用: 确保每个方法参数都有其明确的用途。在原始代码中,showConnections的layOverVertex参数未被有效利用,导致逻辑错误。重构后,我们将其拆分为layOverCityLabel和distanceToLayover,使其职责更清晰。
  • 职责单一原则: 每个方法应只负责一项明确的任务。getConnections负责获取特定节点的邻接列表,showConnections则负责格式化并显示这些连接及其总距离。避免一个方法承担过多不相关的职责。
  • 错误处理: 在main方法中,我们增加了对layOverVertexFromStart == null的检查,以处理用户输入无效中转城市或该城市无法从起始城市直接到达的情况。
  • 代码可读性: 使用有意义的变量名和清晰的输出格式可以大大提高代码的可读

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1030

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

254

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1089

2024.03.01

php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

267

2025.12.04

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1566

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

649

2023.11.24

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.3万人学习

C# 教程
C# 教程

共94课时 | 11.2万人学习

Java 教程
Java 教程

共578课时 | 81.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号