您现在的位置是:首页 > 编程 > 

C语言之装甲车库车辆动态监控辅助记录系统

2025-07-22 09:51:56
C语言之装甲车库车辆动态监控辅助记录系统 C语言之装甲车库车辆动态监控辅助记录系统一、前言(一)问题描述设计一个狭长通道装甲车库车辆动态监控辅助记录系统的管理程序,实现装甲车默认按先后顺序停放,也可以自选位置停放、出场时让装甲车按车牌号离开车库的功能。 (二)算法输入装甲车入场: 用户选择菜单中的“1. 装甲车辆入场”功能。 输入车牌号 MD521,输入油量百分比:85,输入损坏程度百分比:

C语言之装甲车库车辆动态监控辅助记录系统

C语言之装甲车库车辆动态监控辅助记录系统一、前言

(一)问题描述

设计一个狭长通道装甲车库车辆动态监控辅助记录系统的管理程序,实现装甲车默认按先后顺序停放,也可以自选位置停放、出场时让装甲车按车牌号离开车库的功能。

(二)算法输入

装甲车入场: 用户选择菜单中的“1. 装甲车辆入场”功能。 输入车牌号 MD521,输入油量百分比:85,输入损坏程度百分比:0,选择停车位 (1-100):4,系统成功将车辆停放在第4个空闲位置。 系统提示“车辆 MU521 已停入主装甲车库,位置:4”,显示车辆成功入场。

装甲车辆出场: 用户选择菜单中的“2. 装甲车辆出场”功能。 输入要移出的车牌号 MU521,系统成功从停车场移除该车辆。 系统提示“装甲车 MU521 离开主装甲车库,停车时长:0.04 小时”,显示车辆成功出场,并输出停车时长。

装甲车库状态显示: 用户选择菜单中的“. 显示装甲车库状态”功能。 系统打印所有 100 个装甲车库的状态,显示99个装甲车库当前状态为空闲(未停放车辆),一个装甲车,并打印信息。 系统统计装甲车库信息:总容量:100,当前数量:1。位置 4: MU521 (油量: 85%, 损坏: 0%)

搜索装甲车失败: 用户选择菜单中的“4. 按照装甲车牌号查询车辆”功能。 输入车牌号 999,系统未能到该装甲车库,提示“未到车牌号为 999 的车辆”。 说明装甲车可能已出场或未入场。

车辆成功搜索: 用户选择菜单中的“4. 搜索车辆”功能,输入车牌号 MU521,系统成功定位车辆,提示“到装甲车 MU521,位置 4,油量 85%,损坏程度 0%”。

装甲车油量排序: 用户选择菜单中的“5. 查询装甲车辆油量并按油量排序”功能,按照冒泡排序从油量大到小进行排序并输出。

装甲车损坏程度排序: 用户选择菜单中的“6. 查询装甲车辆装备损坏情况并按损坏程度排序”功能,按照快速排序从损坏程度小到大进行排序并输出。

二、算法要点描述与实现思想

(一)算法要点

  1. 装甲车库创建模块: o 使用 createGarage 函数初始化装甲车库,分配内存并设置初始状态,包括前驱和后继指针、容量、大小以及占用状态数组。
  2. 装甲车库状态检查模块: o isFull 函数检查装甲车库是否已满,即当前数量是否达到最大容量。 o isEmpty 函数检查装甲车库是否为空,即当前数量是否为零。
  3. 装甲车辆入场模块: o enterGarage 函数处理装甲车辆的入场,包括用户选择停车位、输入车辆信息,并将其添加到链表中相应的位置。 o 如果主装甲车库未满,将车辆信息添加到主车库的链表中,并更新占用状态。 o 如果主装甲车库已满,将车辆信息添加到临时车库的链表中。
  4. 装甲车辆出场模块: o leaveGarage 函数处理装甲车辆的出场,遍历主装甲车库的链表到对应车辆,并更新链表和占用状态。 o 如果临时车库有车辆,将临时车库中的第一辆车移动到主车库中空出的位置上。
  5. 装甲车库状态显示模块: o displayStatus 函数显示主装甲车库和临时车库的当前状态,包括每个车位的车辆信息和空位。
  6. 装甲车辆搜索模块: o searchVehicle 函数根据车牌号搜索车辆,遍历主装甲车库的链表,到对应车辆后显示其信息。
  7. 装甲车辆油量显示模块: o displayFuelLevels 函数显示主装甲车库中所有车辆的油量信息,并按油量进行冒泡排序。
  8. 装甲车辆损坏程度显示模块: o displayDamageLevels 函数显示主装甲车库中所有车辆的损坏程度信息,并使用快速排序算法按损坏程度排序。
  9. 数据持久化模块: o saveState 和 loadState 函数分别用于保存和加载装甲车库的状态,包括车辆信息和占用状态。
  10. 主控菜单模块: o 程序通过无限循环显示菜单,接收用户的选择,并根据选择调用相应的功能函数。

(二)实现思想

1、输入处理模块

该模块负责接收用户输入的功能选项和装甲车牌号,并对这些输入数据进行处理。 实现思想: 主菜单通过提示用户输入功能编号,并使用 scanf 获取用户输入。 在处理特定功能时,如装甲车辆入场或出场,处理车牌号的输入并检查其合法性,确保车牌号不超出预设的最大长度 MAX_PLATE_LE。

代码语言:javascript代码运行次数:0运行复制
printf("请输入您的选择: ");
if (scanf("%d", &choice) != 1) {
    printf("输入无效,请输入数字。\n");
    // 清除输入缓冲区
    while (getchar() != '\n');
    continue;
}

printf("请输入装甲车牌号: ");
scanf("%s", licensePlate);
if (strlen(licensePlate) >= MAX_PLATE_LE) {
    printf("车牌号过长,请输入不超过%d个字符的车牌号。\n", MAX_PLATE_LE - 1);
    // 清除输入缓冲区
    while (getchar() != '\n');
    continue;
}
2、装甲车库初始化模块

该模块负责在程序启动时将装甲车库的所有车位初始化为空闲状态,并清空车牌号信息。 实现思想: 通过循环遍历所有装甲车库,将每个装甲车库的占用状态设置为未占用(0),并将车牌号信息清空。

代码语言:javascript代码运行次数:0运行复制
void initializeParking(ParkingSpot parking[], int numSpots) {     
	int i;     
	for (i = 0; i < numSpots; i++) {         
	parking[i].isOccupied = false; // 设置为未占用         
	memset(parking[i].licensePlate, 0, sizeof(parking[i].licensePlate)); 
	// 清空车牌号     
	} 
}
、主菜单控制模块

该模块负责显示主菜单,接收用户输入,并根据用户的选择调用相应的功能函数。 实现思想: 使用 while 循环不断显示主菜单,接受用户的选择。 使用 switch 语句根据用户输入调用具体的功能函数。 提供退出选项(当 choice 等于7时),终止循环并退出程序。

代码语言:javascript代码运行次数:0运行复制
 int main() {
    int choice;
    char plate[MAX_PLATE_LE];
    int fuelLevel, damageLevel, garageCapacity;

    mainGarage = createGarage(0);
    tempGarage = createGarage(100);
    loadState();

    if (mainGarage->capacity == 0) {
        printf("请输入主装甲车库容量:");
        scanf("%d", &garageCapacity);
        mainGarage->capacity = garageCapacity;
    }

    while (1) {
        displayMenu();
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                printf("请输入车牌号:");
                scanf("%s", plate);
                printf("请输入油量百分比:");
                scanf("%d", &fuelLevel);
                printf("请输入损坏程度百分比:");
                scanf("%d", &damageLevel);
                enterGarage(plate, fuelLevel, damageLevel);
                break;

            case 2:
                printf("请输入车牌号:");
                scanf("%s", plate);
                leaveGarage(plate);
                break;

            case :
                displayStatus();
                break;

            case 4:
                printf("请输入要查的车牌号:");
                scanf("%s", plate);
                searchVehicle(plate);
                break;

            case 5:
                displayFuelLevels();
                break;

            case 6:
                displayDamageLevels();
                break;

            case 7:
                saveState();
                printf("系统已保存,感谢使用!\n");
                free(mainGarage);
                free(tempGarage);
                return 0;

            default:
                printf("无效选择,请重试\n");
        }
    }
    return 0;
}
4、装甲车入场模块

该模块负责将新入场的装甲车停放在第一个可用的停车位上,并更新停车位的状态。 实现思想: 遍历装甲车库的停车位数组,到第一个未被占用的停车位。 将用户输入的装甲车牌号存储到该停车位,并将其状态设置为已占用。 如果装甲车库已满,即没有到空闲停车位,提示用户无法停放车辆。

代码语言:javascript代码运行次数:0运行复制
void enterGarage(char* plate, int fuelLevel, int damageLevel) {
    ode* newode = (ode*)malloc(sizeof(ode));
    if (newode == ULL) {
        perror("Memory allocation failed");
        return;
    }
    strcpy(newode->vehicle.plate, plate);
    newode->vehicle.arriveTime = time(ULL);
    newode->vehicle.fuelLevel = fuelLevel;
    newode->vehicle.damageLevel = damageLevel;
    newode->next = ULL;

    if (!isFull(mainGarage)) {
        int position;
        printf("请选择停装甲车位 (1-%d): ", mainGarage->capacity);
        scanf("%d", &position);

        // Input validation and error handling
        while (position < 1 || position > mainGarage->capacity || mainGarage->occupied[position - 1]) {
            printf("无效的装甲车位选择,该位置已被占用或超出范围。请重新选择 (1-%d): ", mainGarage->capacity);
            scanf("%d", &position);
        }

        mainGarage->occupied[position - 1] = true;

        // Corrected linked list insertion
        ode* current = mainGarage->front;
        ode* prev = ULL;
        int i = 1;
        while (current != ULL && i < position) {
            prev = current;
            current = current->next;
            i++;
        }

        newode->next = current;
        if (prev == ULL) {
            mainGarage->front = newode;
        } else {
            prev->next = newode;
        }
        if (current == ULL) {
            mainGarage->rear = newode;
        }
        mainGarage->size++;
        printf("装甲车 %s 已停入主装甲车库,位置:%d\n", plate, position);
    } else {
        printf("主装甲车库已满,无法停放更多装甲车。\n");
    }
}
5、装甲车出场模块

该模块负责根据用户输入的车牌号到对应的装甲车,将其从停车位上移除,并将停车位状态设置为空闲。 实现思想: 遍历装甲车库的停车位数组,到车牌号匹配的停车位。 将匹配到的停车位状态设置为未占用,并清空车牌号。 如果未到匹配的车牌号,提示用户车辆未到。

代码语言:javascript代码运行次数:0运行复制
void leaveGarage(char* plate) {
    ode* current = mainGarage->front;
    ode* prev = ULL;

    while (current != ULL) {
        if (strcmp(current->vehicle.plate, plate) == 0) {
            if (prev == ULL) {
                mainGarage->front = current->next;
                if (mainGarage->front == ULL) {
                    mainGarage->rear = ULL;
                }
            } else {
                prev->next = current->next;
                if (current->next == ULL) {
                    mainGarage->rear = prev;
                }
            }
            printf("装甲车 %s 离开主装甲车库,停车时长:%.2f 小时\n", plate, difftime(time(ULL), current->vehicle.arriveTime) / 600.0);
            free(current);
            mainGarage->size--;

            // Check if there are any vehicles in the tempGarage to move to mainGarage
            if (!isEmpty(tempGarage)) {
                ode* tempCar = tempGarage->front;
                tempGarage->front = tempGarage->front->next;
                tempGarage->size--;
                tempCar->next = ULL;

                if (isEmpty(mainGarage)) {
                    mainGarage->front = mainGarage->rear = tempCar;
                } else {
                    mainGarage->rear->next = tempCar;
                    mainGarage->rear = tempCar;
                }
                mainGarage->size++;
                printf("便道第一辆装甲车 %s 已进入主装甲车库\n", tempCar->vehicle.plate);
            }
            return;
        }
        prev = current;
        current = current->next;
    }
    printf("未到装甲车牌号为 %s 的装甲车。\n", plate);
}
6、装甲车状态显示模块

该模块负责显示装甲车库中每个停车位的状态,包括是否被占用以及对应的车牌号,并统计显示占用和空闲的停车位数量。 实现思想: 遍历装甲车库的停车位数组,检查每个停车位的状态。 对于每个停车位,输出其位置编号、是否被占用以及车牌号信息。 同时统计已占用和空闲的停车位数量,并在最后显示这些统计信息。

代码语言:javascript代码运行次数:0运行复制
void displayStatus() {
    printf("\n=== 主装甲车库状态 ===\n");
    printf("总容量:%d,当前数量:%d\n", mainGarage->capacity, mainGarage->size);

    ode* current = mainGarage->front; // Start at the beginning of the linked list
    int vehicleIndex = 0;             // Index to track the current vehicle in the list

    for (int i = 0; i < mainGarage->capacity; ++i) {
        if (mainGarage->occupied[i]) {
            if (vehicleIndex < mainGarage->size) { // Check if there's a vehicle to display
                printf("位置 %d: %s (油量: %d%%, 损坏: %d%%)\n", i + 1, current->vehicle.plate, current->vehicle.fuelLevel, current->vehicle.damageLevel);
                current = current->next; // Move to the next vehicle in the list
                vehicleIndex++;
            }
        } else {
            printf("位置 %d: 空\n", i + 1);
        }
    }

    printf("\n=== 临时便道状态 ===\n");
    printf("当前等待数量:%d\n", tempGarage->size);

    current = tempGarage->front;
    int position = 1;
    while (current != ULL) {
        printf("等待位置 %d: %s\n", position++, current->vehicle.plate);
        current = current->next;
    }
}
7、装甲车搜索模块

该模块负责根据用户输入的车牌号在装甲车库中搜索对应的车辆,并返回车辆所在的位置或者提示车辆未到。 实现思想: 遍历装甲车库的停车位数组,查与输入车牌号匹配的停车位。 如果到匹配的车牌号,返回该车辆的停车位编号。 如果遍历完成后未到匹配的车牌号,提示用户车辆未到。

代码语言:javascript代码运行次数:0运行复制
void searchVehicle(char* plate) {
    ode* current = mainGarage->front;
    int position = 0;

    while (current != ULL) {
        position++;
        if (strcmp(current->vehicle.plate, plate) == 0) {
            // Find the actual parking spot using occupied array
            int parkingSpot = 0;
            for (int i = 0; i < mainGarage->capacity; ++i) {
                if (mainGarage->occupied[i]) {
                    parkingSpot++;
                    if (parkingSpot == position) {
                        printf("到装甲车 %s,位置 %d,油量 %d%%,损坏程度 %d%%\n", plate, i + 1, current->vehicle.fuelLevel, current->vehicle.damageLevel);
                        return;
                    }
                }
            }
            return; //Should not reach here, but added for safety
        }
        current = current->next;
    }

    printf("未到装甲车牌号为 %s 的装甲车。\n", plate);
}
8、油量冒泡排序

该模块负责显示主装甲车库中所有装甲车的油量,并按油量从低到高进行冒泡排序。 实现思想: 遍历主装甲车库的链表,收集所有装甲车的油量信息。 使用排序算法(冒泡排序)对油量信息进行排序。 显示排序后的油量信息及对应装甲车的车牌号和位置。

代码语言:javascript代码运行次数:0运行复制
void displayFuelLevels() {
    ode* current = mainGarage->front;
    int numVehicles = mainGarage->size; // Directly use the size of the garage

    if (numVehicles == 0) {
        printf("装甲车为空\n");
        return;
    }

    // 创建一个数组来存储车辆节点指针和它们的位置
    ode* vehicles[numVehicles];
    int positi[numVehicles];
    int i = 0;

    // 遍历链表填充数组
    while (current != ULL) {
        vehicles[i] = current;
        // 到车辆在占用数组中的位置
        int pos = 0;
        for (int j = 0; j < mainGarage->capacity; j++) {
            if (mainGarage->occupied[j]) {
                pos++;
                if (pos == i + 1) {
                    positi[i] = j + 1;
                    break;
                }
            }
        }
        current = current->next;
        i++;
    }

    // 冒泡排序,根据油量排序
    for (int i = 0; i < numVehicles - 1; i++) {
        for (int j = 0; j < numVehicles - i - 1; j++) {
            if (vehicles[j]->vehicle.fuelLevel > vehicles[j + 1]->vehicle.fuelLevel) {
                // 交换节点
                ode* temp = vehicles[j];
                vehicles[j] = vehicles[j + 1];
                vehicles[j + 1] = temp;
                // 交换位置
                int tempPos = positi[j];
                positi[j] = positi[j + 1];
                positi[j + 1] = tempPos;
            }
        }
    }

    // 显示排序结果
    printf("\n=== 按油量排序(冒泡排序) ===\n");
    for (int i = 0; i < numVehicles; i++) {
        printf("装甲车 %s: 油量 %d%%, 停车位 %d\n", vehicles[i]->vehicle.plate, vehicles[i]->vehicle.fuelLevel, positi[i]);
    }
}
9、损坏程度快速排序

该模块负责显示主装甲车库中所有装甲车的损坏程度,并按损坏程度从低到高进行排序。 实现思想: 遍历主装甲车库的链表,收集所有装甲车的损坏程度信息。 使用排序算法(快速排序)对损坏程度信息进行排序。 显示排序后的损坏程度信息及对应装甲车的车牌号和位置。

代码语言:javascript代码运行次数:0运行复制
void displayDamageLevels() {
    ode* current = mainGarage->front;
    int numVehicles = mainGarage->size;

    if (numVehicles == 0) {
        printf("装甲车库为空\n");
        return;
    }

    // 创建一个数组来存储车辆节点指针和它们的位置
    ode* vehicles[numVehicles];
    int positi[numVehicles];
    int i = 0;

    // 遍历链表填充数组
    while (current != ULL) {
        vehicles[i] = current;
        int pos = 0;
        for (int j = 0; j < mainGarage->capacity; j++) {
            if (mainGarage->occupied[j]) {
                pos++;
                if (pos == i + 1) {
                    positi[i] = j + 1;
                    break;
                }
            }
        }
        current = current->next;
        i++;
    }

    // 快速排序,根据损坏程度排序
    quickSort(vehicles, positi, 0, numVehicles - 1);

    // 显示排序结果
    printf("\n=== 按损坏程度排序(快速排序) ===\n");
    for (int i = 0; i < numVehicles; i++) {
        printf("装甲车 %s: 损坏程度 %d%%, 停车位 %d\n", vehicles[i]->vehicle.plate, vehicles[i]->vehicle.damageLevel, positi[i]);
    }
}

// 快速排序的分区函数
int partition(ode* vehicles[], int positi[], int low, int high) {
    int pivot = vehicles[high]->vehicle.damageLevel;
    int i = low - 1;

    for (int j = low; j <= high - 1; j++) {
        if (vehicles[j]->vehicle.damageLevel <= pivot) {
            i++;
            ode* temp = vehicles[i];
            vehicles[i] = vehicles[j];
            vehicles[j] = temp;
            int tempPos = positi[i];
            positi[i] = positi[j];
            positi[j] = tempPos;
        }
    }

    ode* temp = vehicles[i + 1];
    vehicles[i + 1] = vehicles[high];
    vehicles[high] = temp;
    int tempPos = positi[i + 1];
    positi[i + 1] = positi[high];
    positi[high] = tempPos;

    return i + 1;
}

// 快速排序函数
void quickSort(ode* vehicles[], int positi[], int low, int high) {
    if (low < high) {
        int pivotIndex = partition(vehicles, positi, low, high);
        quickSort(vehicles, positi, low, pivotIndex - 1);
        quickSort(vehicles, positi, pivotIndex + 1, high);
    }
} 
三、数据结构确定和数据类型ADT定义

本程序采用了结构体和数组的数据结构,用于管理装甲车库状态和装甲车信息。具体地,定义了以下数据类型:

代码语言:javascript代码运行次数:0运行复制
// Vehicle 结构体: 用于存储单个装甲车的车辆信息。
typedef struct {
    char plate[MAX_PLATE_LE];  // 车牌号
    time_t arriveTime;          // 到达时间
    int fuelLevel;              // 油量百分比
    int damageLevel;            // 损坏程度百分比
} Vehicle;
// ode 结构体: 用于创建链表节点,表示装甲车库中的每个停车位。
typedef struct ode {
    Vehicle vehicle;           // 装甲车信息
    struct ode* next;        // 指向下一个节点的指针
} ode;
// Garage 结构体:用于管理整个装甲车库,包括链表头节点、尾节点、容量、当前装甲车数量以及停车位占用状态数组。
typedef struct {
    ode* front;              // 链表头节点
    ode* rear;               // 链表尾节点
    int capacity;             // 最大容量
    int size;                 // 当前装甲车数量
    bool* occupied;           // 停车位占用状态数组
} Garage; 
四、主要算法程序框图

程序流程图如下图

• 开始后,系统显示主菜单。 • 用户根据菜单选择不同的操作: o 选择1,输入装甲车的车牌号、油量和损坏程度,将装甲车停入主车库。 o 选择2,输入车牌号,从主车库移除装甲车。 o 选择,显示车库的当前状态。 o 选择4,输入要查的车牌号,搜索装甲车。 o 选择5,按油量排序显示装甲车信息。 o 选择6,按损坏程度排序显示装甲车信息。 o 选择7,保存车库状态并退出系统。 • 系统结束。

五、测试数据及结果分析(含时间、空间复杂度分析)

(一)时间复杂度

时间复杂度分析

  1. 主函数 main() 时间复杂度:O(k),其中 k 为用户选择功能的次数。 说明:主函数中的 while 循环会根据用户的选择执行不同的操作,每次操作的时间复杂度取决于具体的函数实现,但整体复杂度与用户操作次数成正比。
  2. 初始化车库 createGarage() 时间复杂度:O(1)。 说明:该函数执行固定数量的操作来初始化车库,与车库的大小无关。
  3. 检查车库状态 isFull() 和 isEmpty() 时间复杂度:O(1)。 说明:这两个函数仅涉及简单的比较操作,时间复杂度为常数。
  4. 装甲车入场 enterGarage() 时间复杂度:O(n),其中 n 为车库容量。 说明:在最坏情况下,可能需要遍历整个车库来到空闲位置或验证用户选择的位置。
  5. 装甲车出场 leaveGarage() 时间复杂度:O(n),其中 n 为车库容量。 说明:在最坏情况下,需要遍历整个车库链表来到并移除指定的装甲车。
  6. 显示车库状态 displayStatus() 时间复杂度:O(n),其中 n 为车库容量。 说明:该函数需要遍历车库中的每个停车位来显示其状态。
  7. 搜索车辆 searchVehicle() 时间复杂度:O(n),其中 n 为车库容量。 说明:在最坏情况下,需要遍历整个车库链表来查指定的装甲车。
  8. 显示油量和损坏程度排序 displayFuelLevels() 和 displayDamageLevels() 时间复杂度:O(n^2),其中 n 为车库容量。 说明:这两个函数需要对所有装甲车进行排序,使用了冒泡排序或快速排序算法。快速排序的平均时间复杂度为 O(n log n),但在最坏情况下为 O(n^2)。
  9. 数据持久化 saveState() 和 loadState() 时间复杂度:O(n),其中 n 为车库容量。 说明:这两个函数需要遍历车库中的每个装甲车来保存或加载状态。

(二)空间复杂度

空间复杂度分析

  1. 初始化车库 createGarage() 空间复杂度:O(n),其中 n 为车库容量。 说明:需要为 occupied 数组分配空间,其大小与车库容量成正比。
  2. 装甲车入场 enterGarage() 和 装甲车出场 leaveGarage() 空间复杂度:O(1)。 说明:除了输入参数外,不需要额外的空间与车库大小成比例。
  3. 显示车库状态 displayStatus()、搜索车辆 searchVehicle()、显示油量排序 displayFuelLevels() 和 显示损坏程度排序 displayDamageLevels() 空间复杂度:O(n),其中 n 为车库容量。 说明:这些函数可能需要额外的数组来存储装甲车信息或进行排序,其大小与车库容量成正比。
  4. 数据持久化 saveState() 和 loadState() 空间复杂度:O(n),其中 n 为车库容量。 说明:需要为保存或加载的装甲车信息分配空间。
六、设计体会,存在问题及分析

(一)存在问题

车库容量的动态调整问题: 当前系统通过宏定义固定车库容量,缺乏灵活性。在实际应用中,可能需要根据实际情况动态调整车库容量。 数据持久化缺失: 系统关闭后,所有装甲车信息丢失,无法恢复。这对于需要长期运行的管理系统来说是一大缺陷。 搜索效率问题: 在大规模车库中,线性搜索效率低下,影响系统性能。 输入处理机制不足: 系统对用户输入的错误处理较为简单,缺乏智能纠错机制。

(二)遇到困难

功能模块逻辑设计: 设计车辆入场、出场和搜索功能时,需要确保逻辑的一致性和准确性,避免车位的重复分配或错误释放。 输入合法性验证: 处理用户输入时,需要确保输入的合法性,防止非法输入导致程序崩溃。 状态显示布局: 在有限的屏幕空间中清晰地展示大量停车位信息是一个设计挑战。 时间复杂度优化: 平衡代码的简单性和性能优化是一个难点,尤其是在大规模数据集上。

(三)修改与完善

动态调整车库容量: 可以考虑使用动态数据结构,如动态数组或链表,来管理停车位,以便根据需要调整车库容量。 实现数据持久化: 通过文件系统或数据库来保存装甲车信息,即使系统关闭也能恢复数据。 优化搜索算法: 引入更高效的搜索算法,如哈希表或二分搜索,以提高大规模数据集的搜索效率。 增强输入处理: 实现更智能的输入验证和错误处理机制,提供用户友好的反馈和纠错建议。

附录代码:代码语言:javascript代码运行次数:0运行复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>


#define MAX_PLATE_LE 20
#define SAVE_FILE "garage_"

// 车辆信息结构体
typedef struct {
    char plate[MAX_PLATE_LE];  // 车牌号
    time_t arriveTime;          // 到达时间
    int fuelLevel;             // 油量百分比
    int damageLevel;           // 损坏程度百分比
} Vehicle;

// 装甲车库节点结构体
typedef struct ode {
    Vehicle vehicle;
    struct ode* next;
} ode;

// 装甲车库队列结构体
typedef struct {
    ode* front;
    ode* rear;
    int capacity;    // 最大容量
    int size;        // 当前数量
    bool* occupied; // 停车位占用状态数组
} Garage;

Garage* mainGarage;
Garage* tempGarage;

Garage* createGarage(int capacity);
int isFull(Garage* garage);
int isEmpty(Garage* garage);
void enterGarage(char* plate, int fuelLevel, int damageLevel);
void leaveGarage(char* plate);
void displayStatus();
void searchVehicle(char* plate);
void displayFuelLevels();
void displayDamageLevels();
void displayMenu();
void saveState();
void loadState();


Garage* createGarage(int capacity) {
    Garage* garage = (Garage*)malloc(sizeof(Garage));
    if (garage == ULL) {
        perror("Memory allocation failed for garage");
        exit(1); // Exit with an error code
    }
    garage->front = garage->rear = ULL;
    garage->capacity = capacity;
    garage->size = 0;
    garage->occupied = (bool*)calloc(capacity, sizeof(bool)); // Allocate memory for occupied array
    if (garage->occupied == ULL) {
        perror("Memory allocation failed for occupied array");
        free(garage); // Free the garage memory since allocation failed
        exit(1); // Exit with an error code
    }
    return garage;
}

int isFull(Garage* garage) {
    return garage->size >= garage->capacity;
}

int isEmpty(Garage* garage) {
    return garage->size == 0;
}

void enterGarage(char* plate, int fuelLevel, int damageLevel) {
    ode* newode = (ode*)malloc(sizeof(ode));
    if (newode == ULL) {
        perror("Memory allocation failed");
        return;
    }
    strcpy(newode->vehicle.plate, plate);
    newode->vehicle.arriveTime = time(ULL);
    newode->vehicle.fuelLevel = fuelLevel;
    newode->vehicle.damageLevel = damageLevel;
    newode->next = ULL;

    if (!isFull(mainGarage)) {
        int position;
        printf("请选择停装甲车位 (1-%d): ", mainGarage->capacity);
        scanf("%d", &position);

        // Input validation and error handling
        while (position < 1 || position > mainGarage->capacity || mainGarage->occupied[position - 1]) {
            printf("无效的装甲车位选择,该位置已被占用或超出范围。请重新选择 (1-%d): ", mainGarage->capacity);
            scanf("%d", &position);
        }

        mainGarage->occupied[position - 1] = true;

        // Corrected linked list insertion
        ode* current = mainGarage->front;
        ode* prev = ULL;
        int i = 1;
        while (current != ULL && i < position) {
            prev = current;
            current = current->next;
            i++;
        }

        newode->next = current;
        if (prev == ULL) {
            mainGarage->front = newode;
        } else {
            prev->next = newode;
        }
        if (current == ULL) {
            mainGarage->rear = newode;
        }
        mainGarage->size++;
        printf("装甲车 %s 已停入主装甲车库,位置:%d\n", plate, position);
    } else {
        // 临时车位处理
        if (isEmpty(tempGarage)) {
            tempGarage->front = tempGarage->rear = newode;
        } else {
            tempGarage->rear->next = newode;
            tempGarage->rear = newode;
        }
        tempGarage->size++;
        printf("主装甲车库已满,装甲车车辆 %s 已停入临时便道,位置:%d\n", plate, tempGarage->size);
    }
}

void leaveGarage(char* plate) {
    ode* current = mainGarage->front;
    ode* prev = ULL;

    while (current != ULL) {
        if (strcmp(current->vehicle.plate, plate) == 0) {
            if (prev == ULL) {
                mainGarage->front = current->next;
                if (mainGarage->front == ULL) {
                    mainGarage->rear = ULL;
                }
            } else {
                prev->next = current->next;
                if (current->next == ULL) {
                    mainGarage->rear = prev;
                }
            }
            printf("装甲车 %s 离开主装甲车库,停车时长:%.2f 小时\n", plate, difftime(time(ULL), current->vehicle.arriveTime) / 600.0);
            free(current);
            mainGarage->size--;

            if (!isEmpty(tempGarage)) {
                ode* tempCar = tempGarage->front;
                tempGarage->front = tempGarage->front->next;
                tempGarage->size--;
                tempCar->next = ULL;

                if (isEmpty(mainGarage)) {
                    mainGarage->front = mainGarage->rear = tempCar;
                } else {
                    mainGarage->rear->next = tempCar;
                    mainGarage->rear = tempCar;
                }
                mainGarage->size++;
                printf("便道第一辆装甲车 %s 已进入主装甲车库\n", tempCar->vehicle.plate);
            }
            return;
        }
        prev = current;
        current = current->next;
    }
    printf("未到装甲车 %s\n", plate);
}


void displayFuelLevels() {
    ode* current = mainGarage->front;
    int numVehicles = mainGarage->size; // Directly use the size of the garage

    if (numVehicles == 0) {
        printf("装甲车为空\n");
        return;
    }

    ode* vehicles[numVehicles];
    int positi[numVehicles];
    int i = 0;

    // Correctly iterate through the linked list to populate the arrays
    while (current != ULL) {
        vehicles[i] = current;
        // Find the position of the vehicle in the occupied array
        int pos = 0;
        for (int j = 0; j < mainGarage->capacity; j++) {
            if (mainGarage->occupied[j]) {
                pos++;
                if (pos == i + 1) {
                    positi[i] = j + 1;
                    break;
                }
            }
        }
        current = current->next;
        i++;
    }

    // 冒泡排序
    for (int i = 0; i < numVehicles - 1; i++) {
        for (int j = 0; j < numVehicles - i - 1; j++) {
            if (vehicles[j]->vehicle.fuelLevel < vehicles[j + 1]->vehicle.fuelLevel) {
                ode* temp = vehicles[j];
                vehicles[j] = vehicles[j + 1];
                vehicles[j + 1] = temp;
                int tempPos = positi[j];
                positi[j] = positi[j + 1];
                positi[j + 1] = tempPos;
            }
        }
    }

    printf("\n=== 按油量排序(冒泡排序) ===\n");
    for (int i = 0; i < numVehicles; i++) {
        printf("装甲车 %s: 油量 %d%%, 停车位 %d\n", vehicles[i]->vehicle.plate, vehicles[i]->vehicle.fuelLevel, positi[i]);
    }
}

// 快速排序
int partition(ode* vehicles[], int positi[], int low, int high) {
    int pivot = vehicles[high]->vehicle.damageLevel;
    int i = low - 1;

    for (int j = low; j <= high - 1; j++) {
        if (vehicles[j]->vehicle.damageLevel <= pivot) {
            i++;
            ode* temp = vehicles[i];
            vehicles[i] = vehicles[j];
            vehicles[j] = temp;
            int tempPos = positi[i];
            positi[i] = positi[j];
            positi[j] = tempPos;
        }
    }

    ode* temp = vehicles[i + 1];
    vehicles[i + 1] = vehicles[high];
    vehicles[high] = temp;
    int tempPos = positi[i + 1];
    positi[i + 1] = positi[high];
    positi[high] = tempPos;

    return i + 1;
}

void quickSort(ode* vehicles[], int positi[], int low, int high) {
    if (low < high) {
        int pivotIndex = partition(vehicles, positi, low, high);
        quickSort(vehicles, positi, low, pivotIndex - 1);
        quickSort(vehicles, positi, pivotIndex + 1, high);
    }
}

void displayDamageLevels() {
    ode* current = mainGarage->front;
    int numVehicles = mainGarage->size;

    if (numVehicles == 0) {
        printf("装甲车库为空\n");
        return;
    }

    ode* vehicles[numVehicles];
    int positi[numVehicles];
    int i = 0;

    while (current != ULL) {
        vehicles[i] = current;
        int pos = 0;
        for (int j = 0; j < mainGarage->capacity; j++) {
            if (mainGarage->occupied[j]) {
                pos++;
                if (pos == i + 1) {
                    positi[i] = j + 1;
                    break;
                }
            }
        }
        current = current->next;
        i++;
    }

    quickSort(vehicles, positi, 0, numVehicles - 1);

    printf("\n=== 按损坏程度排序(快速排序) ===\n");
    for (int i = 0; i < numVehicles; i++) {
        printf("装甲车 %s: 损坏程度 %d%%, 停车位 %d\n", vehicles[i]->vehicle.plate, vehicles[i]->vehicle.damageLevel, positi[i]);
    }
}

void displayStatus() {
    printf("\n=== 主装甲车库状态 ===\n");
    printf("总容量:%d,当前数量:%d\n", mainGarage->capacity, mainGarage->size);

    ode* current = mainGarage->front; // Start at the beginning of the linked list
    int vehicleIndex = 0;             // Index to track the current vehicle in the list

    for (int i = 0; i < mainGarage->capacity; ++i) {
        if (mainGarage->occupied[i]) {
            if (vehicleIndex < mainGarage->size) { // Check if there's a vehicle to display
                printf("位置 %d: %s (油量: %d%%, 损坏: %d%%)\n", i + 1, current->vehicle.plate, current->vehicle.fuelLevel, current->vehicle.damageLevel);
                current = current->next; // Move to the next vehicle in the list
                vehicleIndex++;
            }
        } else {
            printf("位置 %d: 空\n", i + 1);
        }
    }

    printf("\n=== 临时便道状态 ===\n");
    printf("当前等待数量:%d\n", tempGarage->size);

    current = tempGarage->front;
    int position = 1;
    while (current != ULL) {
        printf("等待位置 %d: %s\n", position++, current->vehicle.plate);
        current = current->next;
    }
}

void loadState() {
    FILE* file = fopen(SAVE_FILE, "r");
    if (!file) {
        printf("未到保存文件,将初始化系统。\n");
        return;
    }

    fscanf(file, "%d", &mainGarage->capacity);
    mainGarage->size = 0;
    mainGarage->front = mainGarage->rear = ULL;

    char plate[MAX_PLATE_LE];
    int fuelLevel, damageLevel;
    time_t arriveTime;
    while (fscanf(file, "%s %ld %d %d", plate, &arriveTime, &fuelLevel, &damageLevel) == 4) {
        enterGarage(plate, fuelLevel, damageLevel);
    }

    fclose(file);
    printf("系统状态已加载。\n");
}

void saveState() {
    FILE* file = fopen(SAVE_FILE, "w");
    if (!file) {
        printf("保存失败。\n");
        return;
    }

    fprintf(file, "%d\n", mainGarage->capacity);
    ode* current = mainGarage->front;

    while (current) {
        fprintf(file, "%s %ld %d %d\n", current->vehicle.plate, current->vehicle.arriveTime,
                current->vehicle.fuelLevel, current->vehicle.damageLevel);
        current = current->next;
    }

    fclose(file);
    printf("系统状态已保存。\n");
}

void searchVehicle(char* plate) {
    ode* current = mainGarage->front;
    int position = 0;

    while (current != ULL) {
        position++;
        if (strcmp(current->vehicle.plate, plate) == 0) {
            // Find the actual parking spot using occupied array
            int parkingSpot = 0;
            for (int i = 0; i < mainGarage->capacity; ++i) {
                if (mainGarage->occupied[i]) {
                    parkingSpot++;
                    if (parkingSpot == position) {
                        printf("到装甲车 %s,位置 %d,油量 %d%%,损坏程度 %d%%\n", plate, i + 1, current->vehicle.fuelLevel, current->vehicle.damageLevel);
                        return;
                    }
                }
            }
            return; //Should not reach here, but added for safety
        }
        current = current->next;
    }

    printf("未到装甲车牌号为 %s 的装甲车。\n", plate);
}

void displayMenu() {
    printf("\n=== 装甲车库车辆动态监控辅助记录系统 ===\n");
    printf("1. 装甲车辆入场\n");
    printf("2. 装甲车辆出场\n");
    printf(". 显示装甲车库状态\n");
    printf("4. 按照装甲车牌号查询车辆\n");
    printf("5. 查询装甲车辆油量并按油量排序\n");
    printf("6. 查询装甲车辆装备损坏情况并按损坏程度排序\n");
    printf("7. 保存并退出系统\n");
    printf("请选择操作 (1-7): ");
}

int main() {
    int choice;
    char plate[MAX_PLATE_LE];
    int fuelLevel, damageLevel, garageCapacity;

    mainGarage = createGarage(0);
    tempGarage = createGarage(100);
    loadState();

    if (mainGarage->capacity == 0) {
        printf("请输入主装甲车库容量:");
        scanf("%d", &garageCapacity);
        mainGarage->capacity = garageCapacity;
    }

    while (1) {
        displayMenu();
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                printf("请输入车牌号:");
                scanf("%s", plate);
                printf("请输入油量百分比:");
                scanf("%d", &fuelLevel);
                printf("请输入损坏程度百分比:");
                scanf("%d", &damageLevel);
                enterGarage(plate, fuelLevel, damageLevel);
                break;

            case 2:
                printf("请输入车牌号:");
                scanf("%s", plate);
                leaveGarage(plate);
                break;

            case :
                displayStatus();
                break;

            case 4:
                printf("请输入要查的车牌号:");
                scanf("%s", plate);
                searchVehicle(plate);
                break;

            case 5:
                displayFuelLevels();
                break;

            case 6:
                displayDamageLevels();
                break;

            case 7:
                saveState();
                printf("系统已保存,感谢使用!\n");
                free(mainGarage);
                free(tempGarage);
                return 0;

            default:
                printf("无效选择,请重试\n");
        }
    }
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2025-01-20,如有侵权请联系 cloudcommunity@tencent 删除函数监控排序数组系统

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1164329.html

相关标签:无
上传时间: 2025-07-21 00:35:30
留言与评论(共有 16 条评论)
本站网友 菜单制作
25分钟前 发表
如哈希表或二分搜索
本站网友 阿拉坦五味丸
4分钟前 发表
MAX_PLATE_LE - 1); // 清除输入缓冲区 while (getchar() != '\n'); continue; }2
本站网友 姚志胜
30分钟前 发表
并更新链表和占用状态
本站网友 r516
1分钟前 发表
"); scanf("%s"
本站网友 炫舞八音
30分钟前 发表
线性搜索效率低下
本站网友 中国照相馆
21分钟前 发表
并输出停车时长
本站网友 三仁汤
14分钟前 发表
缺乏灵活性
本站网友 医疗器械经营
1秒前 发表
typedef struct ode { Vehicle vehicle; // 装甲车信息 struct ode* next; // 指向下一个节点的指针 } ode; // Garage 结构体:用于管理整个装甲车库
本站网友 许留山团购
17分钟前 发表
其中 n 为车库容量
本站网友 好玩的网站
9分钟前 发表
位置:4”
本站网友 满书雯
16分钟前 发表
油量 85%
本站网友 黑豆怎么吃最好
23分钟前 发表
positi
本站网友 editplus3
13分钟前 发表
\n"); } void saveState() { FILE* file = fopen(SAVE_FILE
本站网友 捷波朗
19分钟前 发表
\n"); // 清除输入缓冲区 while (getchar() != '\n'); continue; } printf("请输入装甲车牌号
本站网友 常州信息技术职业学院
5分钟前 发表
current->vehicle.fuelLevel