优化Java航班路径显示:中转城市连接与累计距离计算教程

优化java航班路径显示:中转城市连接与累计距离计算教程

本文旨在指导读者如何在Java中实现一个航班路径程序,使其能够准确地显示从用户指定的中转城市出发的所有后续连接,并计算从起始城市到最终目的地的总距离。通过分析现有代码的不足,我们将重点优化`showConnections`方法,使其能够有针对性地获取并展示特定中转城市的出港航班及其累计飞行距离,从而提高程序的逻辑准确性和可读性。

1. 引言:理解航班连接与距离计算的需求

在构建航班路径管理系统时,一个常见需求是根据用户的选择,显示从某一特定中转城市出发的所有直达航班,并计算从整个行程起点到这些后续目的地的总距离。例如,如果从芝加哥(Chicago)出发,经纽约(New York)中转,我们不仅要列出从纽约出发的航班,还要显示“芝加哥 -> 纽约 -> 目的地”的总距离。

原始代码尝试通过showConnections方法实现这一功能,但存在逻辑上的偏差,导致其遍历了整个航班图,而非仅仅是中转城市的连接。本教程将详细介绍如何修正这一问题,实现精确的连接显示和距离累计。

2. 初始代码分析与存在的问题

让我们首先审视原始代码中HWDriverPrep.java的showConnections方法及其辅助方法connect:

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

// HWDriverPrep.java (原始代码片段)private static void showConnections(HWGraph g, Vertex layOverVertex) {    g.graphMap.forEach(            (key, value) -> connect(key, value));}private static void connect(String key, ArrayList value) {    for(Vertex v : value){        System.out.println("City: " + v.label + " Distance: " + v.weight);    }}

问题点分析:

showConnections方法的遍历范围不准确: g.graphMap.forEach((key, value) -> connect(key, value))这行代码遍历了HWGraph中存储的所有城市及其连接,而不是仅限于用户选择的中转城市layOverVertex。这意味着无论用户选择哪个中转城市,程序都会尝试打印出图中所有城市的连接,与实际需求不符。connect方法缺乏上下文信息: connect方法在被调用时,只接收了当前遍历到的城市key和其直连的value(一个ArrayList)。它不知道当前正在处理的是否是用户指定的中转城市,也不知道从起始城市到中转城市的距离。因此,它无法计算“起始城市 -> 中转城市 -> 目的地”的总距离。layOverVertex参数未被充分利用: showConnections方法接收的layOverVertex参数包含了中转城市的标签(layOverVertex.label)和从起始城市到中转城市的距离(layOverVertex.weight)。这些关键信息在原始实现中并未被有效利用来过滤连接或计算总距离。

3. 核心解决方案:精准定位与距离累计

要解决上述问题,我们需要对showConnections方法进行根本性改造。核心思路是:

精准定位中转城市连接: 利用HWGraph类中已有的getConnections(String label)方法,直接获取中转城市的所有出港连接,避免遍历整个图。传递并累计距离: 将从起始城市到中转城市的距离作为基准,与中转城市到后续目的地的直飞距离相加,得到完整的总距离。

4. 重构showConnections方法

我们将废弃原有的connect辅助方法,将其逻辑直接整合到重构后的showConnections中,并确保layOverVertex的所有信息得到充分利用。

以下是修正后的showConnections方法实现:

小爱开放平台 小爱开放平台

小米旗下小爱开放平台

小爱开放平台 281 查看详情 小爱开放平台

// HWDriverPrep.java (修正后的代码片段)private static void showConnections(HWGraph g, Vertex layOverVertex) {    // 1. 获取中转城市的标签    String layOverCityLabel = layOverVertex.label;    // 2. 获取从起始城市到中转城市的距离    int distanceToLayover = layOverVertex.weight;    // 3. 使用HWGraph的getConnections方法,获取中转城市的所有出港连接    ArrayList onwardConnections = g.getConnections(layOverCityLabel);    System.out.printf("\n从 %s 中转的连接 (起始城市到中转城市距离: %d):\n", layOverCityLabel, distanceToLayover);    if (onwardConnections != null && !onwardConnections.isEmpty()) {        for (Vertex onwardCity : onwardConnections) {            // 4. 计算总距离:起始城市 -> 中转城市 -> 后续城市            int totalDistance = distanceToLayover + onwardCity.weight;            System.out.printf("  -> %s (直飞距离: %d, 总距离: %d)\n",                              onwardCity.label, onwardCity.weight, totalDistance);        }    } else {        System.out.printf("  从 %s 没有后续连接。\n", layOverCityLabel);    }}

代码解释:

layOverCityLabel:直接从layOverVertex中提取中转城市的名称。distanceToLayover:从layOverVertex中提取从起始城市到中转城市的距离。这个Vertex对象是由g.getThisVertex(startCity, layOver)返回的,其weight属性恰好存储了这一段的距离。g.getConnections(layOverCityLabel):这是关键一步,它直接从图结构中获取了layOverCityLabel所代表城市的所有直连出港航班。循环遍历onwardConnections:对于每一个从layOverCityLabel出发的后续城市onwardCity,我们计算其totalDistance。totalDistance:等于distanceToLayover(起始到中转)加上onwardCity.weight(中转到后续城市)。输出格式:清晰地展示了后续城市、中转到后续的直飞距离以及从起始城市算起的总距离。

5. 完整的HWDriverPrep.java示例

为了更好地展示如何集成上述修改,以下是完整的HWDriverPrep.java代码,其中包含了创建图、获取用户输入以及调用修正后showConnections方法的逻辑。

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 keys = g.getKeys();        String startCity = "Chicago"; // 示例起始城市        // 获取用户输入的中转城市        String layOver = getLayOverCity(keys, startCity);        // 获取从起始城市到中转城市的Vertex对象,其中包含了该段的距离        Vertex layOverVertex = g.getThisVertex(startCity, layOver);        if (layOverVertex == null) {            System.out.println("错误:无法找到从 " + startCity + " 到 " + layOver + " 的直飞路径,请检查输入。");            return;        }        System.out.printf("\n起始城市: %s, 中转城市: %s (距离: %d)\n", startCity, layOverVertex.label, layOverVertex.weight);        // 调用修正后的showConnections方法,显示中转城市的所有连接及总距离        showConnections(g, layOverVertex);    }    // 辅助方法:打印整个图结构(可选,用于调试)    private static void printGraph(HWGraph g) {        System.out.println("--- 完整航班图结构 ---");        g.graphMap.forEach(                (key, value) -> show(key, value));        System.out.println("--------------------");    }    // 辅助方法:显示单个城市的连接(用于printGraph)    private static void show(String key, ArrayList value) {        System.out.println("城市: " + key + " 的连接:");        for(Vertex v : value){            System.out.println("  -> " + v.label + " (距离: " + v.weight + ")");        }    }    // 辅助方法:获取用户输入的中转城市    private static String getLayOverCity(Set keys, String startCity) {        Scanner s = new Scanner(System.in);        StringBuilder oStr = new StringBuilder();        String cm = "";        for(String item: keys) {            oStr.append(cm).append(item);            cm = ", ";        }        System.out.printf("请选择一个中转城市 (%s): ", oStr.toString());        String retItem = s.nextLine();        return retItem;    }    // 修正后的方法:显示中转城市的连接及总距离    private static void showConnections(HWGraph g, Vertex layOverVertex) {        String layOverCityLabel = layOverVertex.label;        int distanceToLayover = layOverVertex.weight; // 从起始城市到中转城市的距离        ArrayList onwardConnections = g.getConnections(layOverCityLabel);        System.out.printf("\n从 %s 中转的连接 (起始城市到中转城市距离: %d):\n", layOverCityLabel, distanceToLayover);        if (onwardConnections != null && !onwardConnections.isEmpty()) {            for (Vertex onwardCity : onwardConnections) {                int totalDistance = distanceToLayover + onwardCity.weight;                System.out.printf("  -> %s (直飞距离: %d, 总距离: %d)\n",                                  onwardCity.label, onwardCity.weight, totalDistance);            }        } else {            System.out.printf("  从 %s 没有后续连接。\n", layOverCityLabel);        }    }    // 创建航班图数据    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");        // --- 添加连接        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;    }}

6. Vertex.java 和 HWGraph.java (无变化)

这两个类保持不变,因为它们的设计已经足以支持上述逻辑。

Vertex.java:

public class Vertex {    String label;    int weight;    public Vertex(String label, int weight) {        this.label = label;        this.weight = weight;    }}

HWGraph.java:

import java.util.ArrayList;import java.util.HashMap;import java.util.Set;public class HWGraph {    public HashMap<String, ArrayList> graphMap = new HashMap();    public void addVertex( String label ){        ArrayList items = new ArrayList();        graphMap.put( label, items);    }    public void removeVertex( String label ){        // 移除顶点及其所有相关边,此处未实现    }    public void addEdge( String label1, Vertex v){        // 添加从 label1 到 v.label 的有向边,权重为 v.weight        graphMap.get(label1).add(v);    }    ArrayList getConnections( String label){        // 获取指定城市的所有出港连接        return graphMap.get(label);    }    Set getKeys( ){        // 获取所有城市的标签        Set keys = graphMap.keySet();        return keys;    }    Vertex getThisVertex( String startCity, String destCity){        // 获取从 startCity 到 destCity 的直飞 Vertex 对象,包含距离        ArrayList destCities = this.getConnections( startCity);        if (destCities != null) {            for( Vertex v : destCities){                if ( v.label.equalsIgnoreCase(destCity)){                    return v;                }            }        }        return null; // 如果没有找到直飞路径    }}

7. 注意事项与最佳实践

错误处理: 在main方法中,我们添加了对layOverVertex == null的检查。如果用户输入的中转城市无法从起始城市直飞到达,getThisVertex会返回null。良好的错误处理能够提升用户体验。图的表示: 当前的HWGraph是一个有向图,其中addEdge只添加了从label1到v的边。如果需要双向连接(即如果A能飞到B,B也能飞到A),则需要修改addEdge方法,同时添加两条边。灵活性: showConnections方法现在是高度聚焦的。如果未来需要显示所有连接(如printGraph),可以保留或创建单独的方法来处理。用户输入验证: getLayOverCity方法目前没有验证用户输入是否是有效城市。在实际应用中,应该添加逻辑来检查用户输入是否在keys集合中。

8. 总结

通过对showConnections方法进行重构,我们解决了原始代码中遍历范围不准确和缺乏上下文信息的问题。现在,程序能够:

根据用户选择的中转城市,精确地显示其所有后续直飞连接。正确计算从起始城市经过中转城市到达后续目的地的总飞行距离。

这一改进使得航班路径显示功能更加准确、直观,并且代码逻辑也更加清晰和易于维护,体现了在图结构中进行有针对性数据查询和处理的最佳实践。

以上就是优化Java航班路径显示:中转城市连接与累计距离计算教程的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/864411.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
日本重型巡洋舰终极攻略 高机动炮术与战术全解析
上一篇 2025年11月28日 01:24:44
windows10如何完全关闭cortana_windows10Cortana关闭方法
下一篇 2025年11月28日 01:24:47

相关推荐

  • Linux命令行如何查看登录用户

    Linux命令行如何查看登录用户Linux命令行如何查看登录用户Linux命令行如何查看登录用户Linux命令行如何查看登录用户

    答案是 who、w 和 users 命令用于查看Linux系统登录用户,其中 who 显示登录用户及终端信息,w 还显示用户正在执行的命令和系统负载,users 仅输出用户名列表。 在Linux命令行下,要查看当前系统上有哪些用户登录,最直接、最常用的命令包括 who 、 w 和 users 。它们…

    2026年9月21日 用户投稿
    100
  • 虚拟伴侣AI如何实现智能学习 虚拟伴侣AI自适应训练系统的优化指南

    虚拟伴侣AI如何实现智能学习 虚拟伴侣AI自适应训练系统的优化指南虚拟伴侣AI如何实现智能学习 虚拟伴侣AI自适应训练系统的优化指南虚拟伴侣AI如何实现智能学习 虚拟伴侣AI自适应训练系统的优化指南虚拟伴侣AI如何实现智能学习 虚拟伴侣AI自适应训练系统的优化指南

    通过强化学习、记忆网络、多模态融合、联邦学习与课程学习五大机制,构建虚拟伴侣AI的自适应训练系统:一、利用用户反馈信号驱动PPO算法优化对话策略,结合稀疏奖励补偿提升长期决策质量;二、建立增量式上下文记忆网络,以向量数据库存储并检索用户个性化信息,增强长期依赖建模能力;三、融合文本、语音、打字节奏等…

    2026年9月21日 用户投稿
    100
  • 《忍者龙剑传4》PS版画面对比!Pro有专属模式!

    《忍者龙剑传4》PS版画面对比!Pro有专属模式!《忍者龙剑传4》PS版画面对比!Pro有专属模式!《忍者龙剑传4》PS版画面对比!Pro有专属模式!《忍者龙剑传4》PS版画面对比!Pro有专属模式!

    《忍者龙剑传4》(ninja gaiden 4)作为首款深度适配索尼playstation 5 pro硬件特性的动作大作,已于10月21日正式发售。随着媒体评测全面解禁,游戏凭借极致的战斗体验与技术表现赢得广泛赞誉。 本作在标准版PS5与PS5 Pro上均展现出顶尖水准,但得益于更强的GPU与定制A…

    2026年9月21日 用户投稿
    100
  • UC浏览器无法播放YouTube视频怎么办 UC浏览器YouTube播放问题解决方法

    UC浏览器无法播放YouTube视频,通常与浏览器标识、缓存数据或网络设置有关。直接切换到其他主流浏览器是最快解决方案,但如果想继续使用UC浏览器,可以尝试以下方法。 修改浏览器标识(UA) YouTube可能将UC浏览器识别为不兼容的设备,导致视频无法加载。更改UA能解决这个问题。 打开UC浏览器…

    2026年9月21日
    100
  • iPhone 16 Pro如何设置不同铃声给联系人

    在iPhone 16 Pro上为特定联系人设置专属铃声和振动模式,只需进入“通讯录”编辑该联系人,选择“电话铃声”和“振动”选项进行自定义,还可单独设置“短信铃声”,所有设置通过iCloud同步保留。 给iPhone 16 Pro上的特定联系人设置专属铃声很简单,不需要用到电脑或第三方工具。你直接在…

    2026年9月21日
    100
  • 苹果手机密码忘记如何解决

    一、通过Apple ID重设密码 Apple ID是苹果用户的核心账户,可用于找回或重置iPhone的锁屏密码。操作流程如下: 尝试输入密码:在iPhone锁屏界面多次输入错误密码后,系统会提示“iPhone已停用,请稍后再试”。 选择“需要帮助”:当出现锁定提示时,屏幕上通常会显示“忘记密码”或“…

    2026年9月21日
    200
  • mac怎么撤销已发送的信息_Mac撤销已发送信息方法

    答案:Mac上可通过“信息”应用在2分钟内撤回或编辑iMessage消息。操作步骤:1. 悬停消息气泡点击“…”;2. 选择“撤回”或“编辑”;3. 编辑最多5次,超限仅可撤回,对方消息同步删除。 如果您在Mac上使用信息应用发送了消息,但发现内容有误或需要撤回,可以在一定时间内执行撤销操作。此功能…

    2026年9月21日
    000
  • Windows系统下的兼容性问题

    windows兼容性问题严重是因为系统演进快、硬件和软件环境多样。处理此问题需:1.了解目标系统版本和配置;2.使用低版本api或兼容性模式;3.检测操作系统版本并调整程序行为;4.避免依赖特定版本的库,提供多版本安装包;5.考虑硬件依赖性,提供备选方案;6.进行跨版本性能测试和优化。 在Windo…

    2026年9月21日
    000
  • Linux如何限制用户执行特定命令

    Linux如何限制用户执行特定命令Linux如何限制用户执行特定命令Linux如何限制用户执行特定命令Linux如何限制用户执行特定命令

    首选sudo进行命令限制,因其灵活且可审计;通过visudo配置精确的用户权限,结合白名单、命令别名和!语法实现允许或拒绝特定命令;同时防范绕过手段如全路径执行、间接调用、脚本执行等,需多层防御并辅以日志监控。 在Linux环境中,限制用户执行特定命令,最直接有效且灵活的方法通常是利用 sudo 权…

    2026年9月21日 用户投稿
    000
  • 豆包大模型1.6 lite— 字节跳动推出的轻量级AI模型

    豆包大模型1.6 lite— 字节跳动推出的轻量级AI模型豆包大模型1.6 lite— 字节跳动推出的轻量级AI模型豆包大模型1.6 lite— 字节跳动推出的轻量级AI模型豆包大模型1.6 lite— 字节跳动推出的轻量级AI模型

    ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜ 豆包大模型 字节跳动自主研发的一系列大型语言模型 834 查看详情 豆包大模型1.6 lite是什么 豆包大模型1.6 lite(doubao-seed-1.6-lite)是字节跳动推出的轻量级…

    2026年9月21日 用户投稿
    300
  • 在Java中如何使用方法重载

    方法重载允许类中多个同名方法共存,只要参数列表不同即可。例如Calculator类中add方法可接受不同数量、类型或顺序的参数,Java根据传入参数自动匹配对应方法,提升调用灵活性与代码可读性。 方法重载(Overloading)是Java中实现多态的一种方式,它允许在一个类中定义多个同名方法,只要…

    2026年9月21日
    200
  • VSCode的括号着色功能如何帮助你避免语法错误?

    VSCode括号着色功能通过彩色高亮匹配括号,帮助用户直观识别嵌套结构、提升代码可读性,并快速发现遗漏或多余括号,减少语法错误。 VSCode的括号着色功能通过视觉方式帮你快速识别代码中的匹配和嵌套结构,减少语法错误的发生。当你在编写代码时,成对出现的括号(如()、[]、{})会被高亮显示为相同或相…

    2026年9月21日
    000
  • 百度AI开发者大会何时举行_百度AI开发者大会参与指南

    2025百度AI开发者大会于4月25日在武汉体育中心举办,主题为“模型的世界,应用的天下”,发布了两大模型及多款AI应用,参会需通过官网注册报名,审核后获取电子凭证,同时提供线上直播及会后视频回看。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜…

    2026年9月21日
    000
  • UC浏览器下载提示安全风险怎么办 UC浏览器文件下载安全提示解决方法

    首先判断风险真假再操作,确认下载来源是否正规、文件名是否异常,并用VirusTotal扫描;检查UC浏览器“安全与隐私”设置中下载防护功能,可临时关闭但需及时恢复;若仍被拦截,可通过应用商店、官网下载APK或换用其他浏览器获取文件,切勿忽视安全警告。 UC浏览器提示下载文件有安全风险,通常是浏览器或…

    2026年9月21日
    000
  • 抖音商城是哪个公司在运营

    抖音商城的运营主体揭晓 抖音商城由北京微播视界科技有限公司负责运营。 作为抖音背后的母公司,字节跳动通过其全资子公司——微播视界,全面掌舵抖音平台及其电商板块的日常运作。依托雄厚的技术积累与多元化的业务布局,为用户打造流畅、智能且高效的购物环境。 抖音商城究竟是什么? 抖音商城是抖音App内嵌的一站…

    2026年9月21日
    100
  • mysql如何理解索引选择性

    索引选择性是衡量索引效率的关键指标,定义为索引列不同值数量与总行数的比值,范围在0到1之间。越接近1,数据唯一性越高,索引过滤能力越强,查询性能越好。例如主键列选择性为1,而性别列因重复值多选择性极低。MySQL优化器会优先选择高选择性索引以缩小搜索范围,提高执行效率。可通过SELECT COUNT…

    2026年9月21日
    000
  • iPhone 17如何快速清理存储空间

    首先通过系统推荐一键优化释放8-12GB空间,再重点清理微信缓存、合并重复照片并开启优化存储,最后深度清理Safari缓存、删除大型App及关闭自动下载,可高效腾出数十GB存储。 虽然目前还没有iPhone 17,但根据2025年最新的iOS系统清理方法,无论你使用的是哪款iPhone,都可以通过以…

    2026年9月21日
    100
  • 卖不动!iPhone Air暂时停产!库存已经够用了

    据数码博主“定焦数码”透露,苹果iphone air目前已暂停生产。此次调整主要受两方面因素影响:一是该机型在海外市场销量未达预期;二是中国大陆地区的上市时间有所推迟。不过,由于前期已储备了充足的整机库存,当前市场供应不受影响,未来将根据订单积累情况再决定恢复生产的时机。 这一产能变动与此前投资机构…

    2026年9月21日
    000
  • 豆包语音2.0— 字节跳动推出的升级版AI语音模型

    豆包语音2.0是什么 豆包语音2.0是字节跳动推出的升级版ai语音模型,包含两大核心模型:豆包语音合成模型2.0(doubao-seed-tts 2.0)和豆包声音复刻模型2.0(doubao-seed-icl 2.0)。语音合成模型2.0支持对话式合成,可精准理解语义和情感,实现复杂公式朗读,准确…

    2026年9月21日
    100
  • Java中如何将嵌套列表对象转换为扁平化单元素列表

    本文探讨了在java中将包含嵌套列表的对象集合转换为新列表的多种策略,旨在使新列表中每个对象仅包含其嵌套列表中的一个元素。通过详细介绍java 7的传统迭代方法、java 8-15的stream api `flatmap`操作,以及java 16及更高版本的`mapmulti`方法,文章提供了清晰的…

    2026年9月21日
    100

发表回复

登录后才能评论
关注微信