1. 前言
本课程设计旨在开发一个模拟航空订票系统,通过本项目的实施,可以让学生熟悉顺序表(或链表)的创建、查找、插入、删除,文件读写机制。同时,该项目有助于学生掌握面向对象编程、数据结构以及算法的综合应用。
- 目录
目录
3. 任务书
请打印课程设计要求页面。
4. 问题描述
编写程序模拟航空订票系统,要求实现以下功能:
1)允许增、删、改航班信息,包括“航班号 / 机型 / 起降城市 / 起降时间 / 座位数 / 票价等”(所有航班信息存储在本地文本文件中,格式自定义)。
2)允许以“航班号 / 起降城市”等条件模糊查询航班信息。
订票:无票时应能提供相关可选择的航班以继续操作(订票数据存储在本地文本文件中,格式自定义)。
退票:退票后应修改相关数据文件(一次性订多张票时可以只退其中部分票)。
5. 需求分析
功能需求分析
- 航班管理模块:包括航班信息的增、删、改操作。
- 航班查询模块:支持按航班号或起降城市等条件模糊查询航班信息。
- 订票模块:支持用户订票操作,当无票时应推荐其他航班。
- 退票模块:支持退票操作,并更新相关数据文件。
模块划分及数据交互关系
- Flight类:表示单个航班信息,包含航班号、机型、起降城市、时间、座位数和票价等属性。
- FlightManager类:管理系统中所有航班信息,提供增删改查操作。
- Booking类:表示单个订票信息,包含订票编号、航班号、乘客姓名、订票座位数等属性。
- BookingManager类:管理所有订票信息,提供订票和退票操作。
- FileManager类:提供航班信息和订票信息的文件读写操作。
6. 概要设计
类设计
Flight类:存储航班基本信息,提供属性的获取和设置方法。
FlightManager类:负责航班信息的增删改查、文件的保存与读取。
Booking类:存储订票信息,提供属性的获取和设置方法。
BookingManager类:负责订票和退票操作,并更新文件。
FileManager类:处理航班和订票信息的文件读写操作。
7. 详细设计
核心算法伪代码描述与部分源代码
增加航班
- 创建一个新的 Flight 对象,并给属性赋值。
- 将该新航班添加到 FlightManager 的 flights 列表中。
- 将 flights 列表保存到文件中。
- 结束。
伪代码:
方法 addFlight(flight):
flights.append(flight)
saveToFile()
删除航班
- 根据航班号从 flights 列表中找到对应的航班。
- 从 flights 列表中移除该航班。
- 将 flights 列表保存到文件中。
- 结束。
伪代码:
方法 deleteFlight(flightNumber):
for i from 0 to flights.size - 1:
if flights[i].getFlightNumber() == flightNumber:
flights.remove(i)
break
saveToFile()
修改航班
- 根据航班号找到并更新 flights 列表中的对应航班的信息。
- 将 flights 列表保存到文件中。
- 结束。
伪代码:
方法 modifyFlight(updatedFlight):
for i from 0 to flights.size - 1:
if flights[i].getFlightNumber() == updatedFlight.getFlightNumber():
update flights[i] with updatedFlight
break
saveToFile()
航班查询
- 根据航班号或城市从 flights 列表中查找所有符合条件的航班信息。
- 返回符合条件的航班信息列表。
- 结束。
伪代码:
方法 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
订票
- 根据航班号从 flights 列表中找到对应的航班。
- 检查该航班是否有足够的座位。
- 如果有足够的座位,将订票信息添加到 bookings 列表中,并减少该航班的座位数。
- 将 bookings 和 flights 列表保存到文件中。
- 结束。
伪代码:
方法 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"
退票
- 根据订票编号从 bookings 列表中找到对应的订票信息。
- 在相应的航班中增加座位数。
- 检查是否退订所有座位,如果是则从 bookings 列表中移除此订票,否则更新订票信息。
- 将 bookings 和 flights 列表保存到文件中。
- 结束。
伪代码:
方法 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("退票成功");
}
}