java课程设计-模拟航空订票系统

1. 前言

本课程设计旨在开发一个模拟航空订票系统,通过本项目的实施,可以让学生熟悉顺序表(或链表)的创建、查找、插入、删除,文件读写机制。同时,该项目有助于学生掌握面向对象编程、数据结构以及算法的综合应用。

  1. 目录

目录

1. 前言 

3. 任务书 

4. 问题描述 

5. 需求分析 

功能需求分析 

模块划分及数据交互关系 

6. 概要设计 

类设计 

7. 详细设计 

8. 调试分析 

9. 运行结果 

10. 小结 

11. 参考文献 

12. 附录 

3. 任务书

请打印课程设计要求页面。

4. 问题描述

编写程序模拟航空订票系统,要求实现以下功能:

1)允许增、删、改航班信息,包括“航班号 / 机型 / 起降城市 / 起降时间 / 座位数 / 票价等”(所有航班信息存储在本地文本文件中,格式自定义)。

2)允许以“航班号 / 起降城市”等条件模糊查询航班信息。

订票:无票时应能提供相关可选择的航班以继续操作(订票数据存储在本地文本文件中,格式自定义)。

退票:退票后应修改相关数据文件(一次性订多张票时可以只退其中部分票)。

5. 需求分析

功能需求分析

  1. 航班管理模块:包括航班信息的增、删、改操作。
  2. 航班查询模块:支持按航班号或起降城市等条件模糊查询航班信息。
  3. 订票模块:支持用户订票操作,当无票时应推荐其他航班。
  4. 退票模块:支持退票操作,并更新相关数据文件。

模块划分及数据交互关系

  • Flight类:表示单个航班信息,包含航班号、机型、起降城市、时间、座位数和票价等属性。
  • FlightManager类:管理系统中所有航班信息,提供增删改查操作。
  • Booking类:表示单个订票信息,包含订票编号、航班号、乘客姓名、订票座位数等属性。
  • BookingManager类:管理所有订票信息,提供订票和退票操作。
  • FileManager类:提供航班信息和订票信息的文件读写操作。

6. 概要设计

类设计

Flight类:存储航班基本信息,提供属性的获取和设置方法。

FlightManager类:负责航班信息的增删改查、文件的保存与读取。

Booking类:存储订票信息,提供属性的获取和设置方法。

BookingManager类:负责订票和退票操作,并更新文件。

FileManager类:处理航班和订票信息的文件读写操作。

7. 详细设计

核心算法伪代码描述与部分源代码

增加航班

  1. 创建一个新的 Flight 对象,并给属性赋值。
  2. 将该新航班添加到 FlightManager 的 flights 列表中。
  3. 将 flights 列表保存到文件中。
  4. 结束。

伪代码:

方法 addFlight(flight):

  flights.append(flight)

  saveToFile()

删除航班

  1. 根据航班号从 flights 列表中找到对应的航班。
  2. 从 flights 列表中移除该航班。
  3. 将 flights 列表保存到文件中。
  4. 结束。

伪代码

方法 deleteFlight(flightNumber):

  for i from 0 to flights.size - 1:

    if flights[i].getFlightNumber() == flightNumber:

      flights.remove(i)

      break

  saveToFile()

修改航班

  1. 根据航班号找到并更新 flights 列表中的对应航班的信息。
  2. 将 flights 列表保存到文件中。
  3. 结束。

伪代码:

方法 modifyFlight(updatedFlight):

  for i from 0 to flights.size - 1:

    if flights[i].getFlightNumber() == updatedFlight.getFlightNumber():

      update flights[i] with updatedFlight

      break

  saveToFile()

航班查询

  1. 根据航班号或城市从 flights 列表中查找所有符合条件的航班信息。
  2. 返回符合条件的航班信息列表。
  3. 结束。

伪代码:

方法 queryByFlightNumber(flightNumber):

  result := []

  for i from 0 to flights.size - 1:

    if flights[i].getFlightNumber() == flightNumber:

      result.append(flights[i])

  return result

方法 queryByCity(departureCity, arrivalCity):

  result := []

  for i from 0 to flights.size - 1:

    if flights[i].getDepartureCity() == departureCity AND flights[i].getArrivalCity() == arrivalCity:

      result.append(flights[i])

  return result

订票

  1. 根据航班号从 flights 列表中找到对应的航班。
  2. 检查该航班是否有足够的座位。
  3. 如果有足够的座位,将订票信息添加到 bookings 列表中,并减少该航班的座位数。
  4. 将 bookings 和 flights 列表保存到文件中。
  5. 结束。

伪代码:

方法 bookFlight(booking):

  flight := find flight by booking.flightNumber from flights

  if flight.seats >= booking.numSeats:

    bookings.append(booking)

    flight.seats -= booking.numSeats

    saveBookingsToFile()

    saveFlightsToFile()

  else:

    print "Not enough seats available"

退票

  1. 根据订票编号从 bookings 列表中找到对应的订票信息。
  2. 在相应的航班中增加座位数。
  3. 检查是否退订所有座位,如果是则从 bookings 列表中移除此订票,否则更新订票信息。
  4. 将 bookings 和 flights 列表保存到文件中。
  5. 结束。

伪代码:

方法 cancelBooking(bookingID, numSeats):

  booking := find booking by bookingID from bookings  flight := find flight by booking.flightNumber from flights

  flight.seats += numSeats

  if booking.numSeats == numSeats:

    bookings.remove(booking)  else:

    booking.numSeats -= numSeats

  saveBookingsToFile()

  saveFlightsToFile()

8. 调试分析

调试过程中,常见的问题包括:

文件不存在:确保文件路径正确,并且程序有读写权限。

这是由于程序开始运行时没有创建相应的储存文件导致的空文件问题,需要在正式运行前创建相应文件。

9. 运行结果

输入三组测试数据,检查程序在各种条件下的正确性,如添加航班、查询航班、订票和退票操作。

10. 小结

通过本次课程设计,我们在实践中巩固了顺序表、链表、文件读写等知识。同时,面对实际需求和问题,我们学会了如何进行需求分析、模块设计和代码实现,并在过程中提升了自己的编程能力和解决问题的能力。当然,项目过程中也有一些遗憾,比如在设计文件存储格式时可能需要更多考虑扩展性和兼容性,但在进一步优化中,这些问题可以得到解决。

总的来说,这次课程设计不仅仅是一次编程练习,更是对分析问题、解决问题能力的全面提升。在今后的学习生活中,我们将继续努力,不断完善和提升自己。

11. 参考文献

请列出不少于5篇的参考文献。

《Java编程思想》(第4版),Bruce Eckel

《Effective Java》(第3版),Joshua Bloch

《数据结构与算法分析:Java语言描述》,Mark Allen Weiss

《Java I/O》,Ian Foster

12. 附录

public class Flight {
    private String flightNumber;  // 航班号
    private String aircraftType;  // 机型
    private String departureCity; // 起飞城市
    private String arrivalCity;   // 到达城市
    private String departureTime; // 起飞时间
    private String arrivalTime;   // 到达时间
    private int seats;            // 座位数
    private double fare;          // 票价

    public Flight(String flightNumber, String aircraftType, String departureCity, String arrivalCity,
                  String departureTime, String arrivalTime, int seats, double fare) {
        this.flightNumber = flightNumber;
        this.aircraftType = aircraftType;
        this.departureCity = departureCity;
        this.arrivalCity = arrivalCity;
        this.departureTime = departureTime;
        this.arrivalTime = arrivalTime;
        this.seats = seats;
        this.fare = fare;
    }

    // 获取所有字段的getter和setter方法
    public String getFlightNumber() { return flightNumber; }
    public void setFlightNumber(String flightNumber) { this.flightNumber = flightNumber; }

    public String getAircraftType() { return aircraftType; }
    public void setAircraftType(String aircraftType) { this.aircraftType = aircraftType; }

    public String getDepartureCity() { return departureCity; }
    public void setDepartureCity(String departureCity) { this.departureCity = departureCity; }

    public String getArrivalCity() { return arrivalCity; }
    public void setArrivalCity(String arrivalCity) { this.arrivalCity = arrivalCity; }

    public String getDepartureTime() { return departureTime; }
    public void setDepartureTime(String departureTime) { this.departureTime = departureTime; }

    public String getArrivalTime() { return arrivalTime; }
    public void setArrivalTime(String arrivalTime) { this.arrivalTime = arrivalTime; }

    public int getSeats() { return seats; }
    public void setSeats(int seats) { this.seats = seats; }

    public double getFare() { return fare; }
    public void setFare(double fare) { this.fare = fare; }

    @Override
    public String toString() {
        return flightNumber + " " + aircraftType + " " + departureCity + " " + arrivalCity + " " +
               departureTime + " " + arrivalTime + " " + seats + " " + fare;
    }
}

import java.io.*;
import java.util.*;

public class FlightManager {
    private List<Flight> flights = new ArrayList<>();  // 存储航班信息的列表

    // 从文件加载航班信息
    public void loadFromFile() {
        try (BufferedReader reader = new BufferedReader(new FileReader("flights.txt"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                flights.add(parseFlight(line));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 将航班信息保存到文件
    void saveToFile() {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter("flights.txt"))) {
            for (Flight flight : flights) {
                writer.write(flight.toString());
                writer.newLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 解析一行文本为Flight对象
    private Flight parseFlight(String line) {
        String[] parts = line.split(" ");
        return new Flight(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5],
                Integer.parseInt(parts[6]), Double.parseDouble(parts[7]));
    }

    // 添加航班
    public void addFlight(Flight flight) {
        flights.add(flight);
        saveToFile();
    }

    // 删除航班
    public void deleteFlight(String flightNumber) {
        flights.removeIf(f -> f.getFlightNumber().equals(flightNumber));
        saveToFile();
    }

    // 修改航班信息
    public void modifyFlight(Flight updatedFlight) {
        for (Flight flight : flights) {
            if (flight.getFlightNumber().equals(updatedFlight.getFlightNumber())) {
                flight.setAircraftType(updatedFlight.getAircraftType());
                flight.setDepartureCity(updatedFlight.getDepartureCity());
                flight.setArrivalCity(updatedFlight.getArrivalCity());
                flight.setDepartureTime(updatedFlight.getDepartureTime());
                flight.setArrivalTime(updatedFlight.getArrivalTime());
                flight.setSeats(updatedFlight.getSeats());
                flight.setFare(updatedFlight.getFare());
                break;
            }
        }
        saveToFile();
    }

    // 按航班号查询航班信息
    public List<Flight> queryByFlightNumber(String flightNumber) {
        List<Flight> result = new ArrayList<>();
        for (Flight flight : flights) {
            if (flight.getFlightNumber().contains(flightNumber)) {
                result.add(flight);
            }
        }
        return result;
    }

    // 按起降城市查询航班信息
    public List<Flight> queryByCity(String departureCity, String arrivalCity) {
        List<Flight> result = new ArrayList<>();
        for (Flight flight : flights) {
            if (flight.getDepartureCity().equals(departureCity) && flight.getArrivalCity().equals(arrivalCity)) {
                result.add(flight);
            }
        }
        return result;
    }
}

public class Booking {
    private String bookingID;        // 订票编号
    private String flightNumber;     // 航班号
    private String passengerName;    // 乘客姓名
    private int numSeats;            // 订票座位数

    public Booking(String bookingID, String flightNumber, String passengerName, int numSeats) {
        this.bookingID = bookingID;
        this.flightNumber = flightNumber;
        this.passengerName = passengerName;
        this.numSeats = numSeats;
    }

    // 获取和设置方法
    public String getBookingID() { return bookingID; }
    public void setBookingID(String bookingID) { this.bookingID = bookingID; }

    public String getFlightNumber() { return flightNumber; }
    public void setFlightNumber(String flightNumber) { this.flightNumber = flightNumber; }

    public String getPassengerName() { return passengerName; }
    public void setPassengerName(String passengerName) { this.passengerName = passengerName; }

    public int getNumSeats() { return numSeats; }
    public void setNumSeats(int numSeats) { this.numSeats = numSeats; }

    @Override
    public String toString() {
        return bookingID + " " + flightNumber + " " + passengerName + " " + numSeats;
    }
}

import java.io.*;
import java.util.*;

public class BookingManager {
    private List<Booking> bookings = new ArrayList<>();  // 存储订票信息的列表
    private FlightManager flightManager;                // 航班管理器

    public BookingManager(FlightManager flightManager) {
        this.flightManager = flightManager;
    }

    // 从文件加载订票信息
    public void loadFromFile() {
        try (BufferedReader reader = new BufferedReader(new FileReader("bookings.txt"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                bookings.add(parseBooking(line));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 将订票信息保存到文件
    private void saveToFile() {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter("bookings.txt"))) {
            for (Booking booking : bookings) {
                writer.write(booking.toString());
                writer.newLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 解析一行文本为Booking对象
    private Booking parseBooking(String line) {
        String[] parts = line.split(" ");
        return new Booking(parts[0], parts[1], parts[2], Integer.parseInt(parts[3]));
    }

    // 订票操作
    public void bookFlight(Booking booking) {
        List<Flight> flights = flightManager.queryByFlightNumber(booking.getFlightNumber());
        if (!flights.isEmpty()) {
            Flight flight = flights.get(0);
            if (flight.getSeats() >= booking.getNumSeats()) {
                bookings.add(booking);
                flight.setSeats(flight.getSeats() - booking.getNumSeats());
                flightManager.saveToFile();
                saveToFile();
            } else {
                System.out.println("座位不足,无法预订。");
            }
        } else {
            System.out.println("没有找到相应的航班。");
        }
    }

    // 退票操作
    public void cancelBooking(String bookingID, int numSeats) {
        for (Booking booking : bookings) {
            if (booking.getBookingID().equals(bookingID)) {
                List<Flight> flights = flightManager.queryByFlightNumber(booking.getFlightNumber());
                if (!flights.isEmpty()) {
                    Flight flight = flights.get(0);
                    flight.setSeats(flight.getSeats() + numSeats);
                    flightManager.saveToFile();
                    if (booking.getNumSeats() == numSeats) {
                        bookings.remove(booking);
                    } else {
                        booking.setNumSeats(booking.getNumSeats() - numSeats);
                    }
                    saveToFile();
                } else {
                    System.out.println("没有找到相应的航班,无法退票。");
                }
                break;
            }
        }
    }
}

import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        FlightManager flightManager = new FlightManager();
        BookingManager bookingManager = new BookingManager(flightManager);

        // 加载数据
        flightManager.loadFromFile();
        bookingManager.loadFromFile();

        Scanner scanner = new Scanner(System.in);
        int choice;

        do {
            System.out.println("航空订票系统菜单:");
            System.out.println("1. 添加航班");
            System.out.println("2. 删除航班");
            System.out.println("3. 修改航班");
            System.out.println("4. 查询航班");
            System.out.println("5. 订票");
            System.out.println("6. 退票");
            System.out.println("0. 退出系统");
            System.out.print("请输入你的选择:");
            choice = scanner.nextInt();
            scanner.nextLine();  // 清除换行符

            switch (choice) {
                case 1:
                    addFlight(scanner, flightManager);
                    break;
                case 2:
                    deleteFlight(scanner, flightManager);
                    break;
                case 3:
                    modifyFlight(scanner, flightManager);
                    break;
                case 4:
                    queryFlight(scanner, flightManager);
                    break;
                case 5:
                    bookFlight(scanner, bookingManager);
                    break;
                case 6:
                    cancelBooking(scanner, bookingManager);
                    break;
                case 0:
                    System.out.println("退出系统");
                    break;
                default:
                    System.out.println("无效选择,请重试");
            }
        } while (choice != 0);

        scanner.close();
    }

    private static void addFlight(Scanner scanner, FlightManager flightManager) {
        System.out.print("请输入航班号:");
        String flightNumber = scanner.nextLine();
        System.out.print("请输入机型:");
        String aircraftType = scanner.nextLine();
        System.out.print("请输入起飞城市:");
        String departureCity = scanner.nextLine();
        System.out.print("请输入到达城市:");
        String arrivalCity = scanner.nextLine();
        System.out.print("请输入起飞时间:");
        String departureTime = scanner.nextLine();
        System.out.print("请输入到达时间:");
        String arrivalTime = scanner.nextLine();
        System.out.print("请输入座位数:");
        int seats = scanner.nextInt();
        System.out.print("请输入票价:");
        double fare = scanner.nextDouble();
        scanner.nextLine();  // 清除换行符

        Flight flight = new Flight(flightNumber, aircraftType, departureCity, arrivalCity,
                departureTime, arrivalTime, seats, fare);
        flightManager.addFlight(flight);
        System.out.println("航班添加成功");
    }

    private static void deleteFlight(Scanner scanner, FlightManager flightManager) {
        System.out.print("请输入要删除的航班号:");
        String flightNumber = scanner.nextLine();
        flightManager.deleteFlight(flightNumber);
        System.out.println("航班删除成功");
    }

    private static void modifyFlight(Scanner scanner, FlightManager flightManager) {
        System.out.print("请输入要修改的航班号:");
        String flightNumber = scanner.nextLine();
        Flight flight = flightManager.queryByFlightNumber(flightNumber).get(0);
        if (flight != null) {
            System.out.print("请输入新的机型(原:" + flight.getAircraftType() + "):");
            String aircraftType = scanner.nextLine();
            System.out.print("请输入新的起飞城市(原:" + flight.getDepartureCity() + "):");
            String departureCity = scanner.nextLine();
            System.out.print("请输入新的到达城市(原:" + flight.getArrivalCity() + "):");
            String arrivalCity = scanner.nextLine();
            System.out.print("请输入新的起飞时间(原:" + flight.getDepartureTime() + "):");
            String departureTime = scanner.nextLine();
            System.out.print("请输入新的到达时间(原:" + flight.getArrivalTime() + "):");
            String arrivalTime = scanner.nextLine();
            System.out.print("请输入新的座位数(原:" + flight.getSeats() + "):");
            int seats = scanner.nextInt();
            System.out.print("请输入新的票价(原:" + flight.getFare() + "):");
            double fare = scanner.nextDouble();
            scanner.nextLine();  // 清除换行符

            Flight updatedFlight = new Flight(flightNumber, aircraftType, departureCity, arrivalCity,
                    departureTime, arrivalTime, seats, fare);
            flightManager.modifyFlight(updatedFlight);
            System.out.println("航班修改成功");
        } else {
            System.out.println("没有找到该航班");
        }
    }

    private static void queryFlight(Scanner scanner, FlightManager flightManager) {
        System.out.println("1. 按航班号查询");
        System.out.println("2. 按起降城市查询");
        System.out.print("请输入你的选择:");
        int choice = scanner.nextInt();
        scanner.nextLine();  // 清除换行符

        if (choice == 1) {
            System.out.print("请输入航班号:");
            String flightNumber = scanner.nextLine();
            List<Flight> flights = flightManager.queryByFlightNumber(flightNumber);
            flights.forEach(System.out::println);
        } else if (choice == 2) {
            System.out.print("请输入起飞城市:");
            String departureCity = scanner.nextLine();
            System.out.print("请输入到达城市:");
            String arrivalCity = scanner.nextLine();
            List<Flight> flights = flightManager.queryByCity(departureCity, arrivalCity);
            flights.forEach(System.out::println);
        } else {
            System.out.println("无效选择");
        }
    }

    private static void bookFlight(Scanner scanner, BookingManager bookingManager) {
        System.out.print("请输入订票编号:");
        String bookingID = scanner.nextLine();
        System.out.print("请输入航班号:");
        String flightNumber = scanner.nextLine();
        System.out.print("请输入乘客姓名:");
        String passengerName = scanner.nextLine();
        System.out.print("请输入订票座位数:");
        int numSeats = scanner.nextInt();
        scanner.nextLine();  // 清除换行符

        Booking booking = new Booking(bookingID, flightNumber, passengerName, numSeats);
        bookingManager.bookFlight(booking);
        System.out.println("订票成功");
    }

    private static void cancelBooking(Scanner scanner, BookingManager bookingManager) {
        System.out.print("请输入退票编号:");
        String bookingID = scanner.nextLine();
        System.out.print("请输入退票座位数:");
        int numSeats = scanner.nextInt();
        scanner.nextLine();  // 清除换行符

        bookingManager.cancelBooking(bookingID, numSeats);
        System.out.println("退票成功");
    }
}

PyQt5的QTableWidget中,实现宽度自动适应内容通常有两种方法: 1. **信号槽连接** (Slot Connections): 当单元格的内容发生变化时,你可以监听`currentCellChanged`信号,然后更新对应的宽。以下是示例代码: ```python from PyQt5.QtWidgets import QApplication, QWidget, QTableWidget, QTableWidgetItem from PyQt5.QtCore import pyqtSignal, Qt class CustomTableWidgetItem(QTableWidgetItem): cellContentChanged = pyqtSignal() def textChanged(self, *args, **kwargs): super().textChanged(*args, **kwargs) self.cellContentChanged.emit() class MyWindow(QWidget): def __init__(self): super().__init__() self.table = QTableWidget() self.table.cellContentChanged.connect(self.resize_column_to_content) ... # 初始化表格内容 def resize_column_to_content(self, row, column): col_width = self.table.columnWidth(column) + self.table.verticalHeader().width() self.table.setColumnWidth(column, col_width) if __name__ == "__main__": app = QApplication([]) window = MyWindow() window.show() app.exec_() ``` 这里,我们在`CustomTableWidgetItem`类中添加了一个文本更改信号,当单元格内容变化时会触发。`resize_column_to_content`方法会在接收到信号时,计算当前加上表头宽度后的总宽度,并调整宽。 2. **布局策略** (Layout Strategies): 使用`horizontalHeader().setSectionResizeMode()`,可以设定的大小策略为`QHeaderView.ResizeToContents`,它会自动调整宽以适应内容: ```python self.table.setHorizontalHeaderSectionResizeMode(QHeaderView.ResizeToContents) ``` 这会自动调整所有宽度,使其适应各自的单元格内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值