设停车场内只有一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。
汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车停放在车场的最北端),若车场内已停满n辆汽车,则后来的汽车只能在门外的便道上等候,一旦有车开走,则排在便道上的第一辆车即可开入;当停车场内某辆车要离开时,在它之后开入的车辆必须先退出车场为它让路,待该辆车开出大门外,其它车辆再按原次序进入车场,每辆停放在车场的车在它离开停车场时必须按它停留的时间长短交纳费用。
试为停车场编制按上述要求进行管理的模拟程序。
功能描述以栈模拟停车场,以队列模拟车场外的便道,按照从终端读入的输入数据序列进行模拟管理。
每一组输入数据包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码及到达或离去的时刻,对每一组输入数据进行操作后的输出数据为:若是车辆到达,则输出汽车在停车场内或便道上的停车位置;若是车离去;则输出汽车在停车场内停留的时间和应交纳的费用(在便道上停留的时间不收费)。
栈以顺序结构实现,队列以链表实现系统设计及实现1.头文件及宏定义#include <conio.h>#include <malloc.h>#include <stdio.h>#include <stdlib.h>#include <windows.h>#define ClearScreen() system( "cls" ) // 清空当前屏幕#define setcolor() system("color 2f")//设置背景前景颜色#define Pause( szPrompt ) printf( "%s", szPrompt ),getch()2.时间和汽车信息结构体的定义(部分代码)typedef struct carinformation // 车辆信息{char szRegistrationMark[64]; // 车牌号char szArrivalTime[16]; // 到达时间char szEntranceTime[16]; // 进入停车场(开始计费)时间char szDepartureTime[16]; // 离开时间} TCARINFORMATION, *LPTCARINFORMATION;3.栈和队列的定义(部分代码)typedef struct carqueue // 链队{LPTCARNODE lpHead; // 头结点LPTCARNODE lpRear; // 指向当前队尾的指针int nEffectiveSize; // 当前队中元素个数} TCARQUEUE, *LPTCARQUEUE;4.栈和队列的初始化(部分代码)void InitQueue( LPTCARQUEUE &lpCarQueue ){lpCarQueue = ( LPTCARQUEUE ) malloc( sizeof( TCARQUEUE ) );lpCarQueue->lpHead = ( LPTCARNODE) malloc( sizeof( TCARNODE ) );lpCarQueue->lpHead->lpNext = NULL;lpCarQueue->lpRear = lpCarQueue->lpHead;lpCarQueue->nEffectiveSize = 0;}实现过程1.开始界面:输入车库容量2.输入车辆到达信息3.当车库停满车时临时停到便道上不收车费4.车辆离开后车库有车位便道上的车进入车库并显示离去车的收费记录5.显示车库及便道信息6.停止输入显示制作者信息及退出程序实训心得通过这次实训我对课本上的理论知识有了更深层次的了解,可能在仅一周的时间内学到的东西有限,不过却也是受益非浅,实训本来就是对平常所学的理论知识通过具体的实现表示出来是在完成理论课程学习之后安排的综合实践训练,任何一个优秀的程序员都是从实践中获得经验和教训的。
经过仅仅一周的实训从总体上说收获是很不错的!首先代码的编写能力明显提高,有了想法基本都能顺利表达出来;再者就是数据结构的选择使用能力也有了很大的提高!虽然,平时的实验课我们也有用各种数据做题,但那些都是很明确的该做什么操作,存什么,我们的发挥空间不大一般照做就行,然而这次实习我们却是在自主的选择判断,这本身就是一个很大的提高!但是还是很多的知识不了解,不过收获真的很多,但是最大的收获可能就是对编程的兴趣吧,在一次次的改掉错误,一次次的完成想要的效果后,越写越有感觉,越写越有成就感!当然还收获了无知,更确切的说是自知,原来我们现在什么也不算,还有很多有用的知识等着我们去学习!附录(代码)#include <conio.h>#include <malloc.h>#include <stdio.h>#include <stdlib.h>#include <windows.h>// 清空当前屏幕#define ClearScreen() system( "cls" )//设置背景前景颜色#define setcolor() system("color 2f")// 显示字符串szPrompt 并等待用户按下任意键#define Pause( szPrompt ) printf( "%s", szPrompt ),getch()typedef struct carinformation // 车辆信息{char szRegistrationMark[64]; // 车牌号char szArrivalTime[16]; // 到达时间char szEntranceTime[16]; // 进入停车场(开始计费)时间char szDepartureTime[16]; // 离开时间} TCARINFORMATION, *LPTCARINFORMATION;typedef struct carstack{LPTCARINFORMATION lpCarInformation; // 车辆信息int nTop; // 栈顶元素下标int nStackSize; // 栈容量} TCARSTACK, *LPTCARSTACK;// 初始化栈lpCarStack, 将其容量设置为nSizevoid InitStack( LPTCARSTACK &lpCarStack, int nSize ){lpCarStack = ( LPTCARSTACK ) malloc( sizeof ( TCARSTACK ) ); lpCarStack->lpCarInformation = ( LPTCARINFORMATION ) malloc( nSize * sizeof ( TCARINFORMATION ));lpCarStack->nTop = -1;lpCarStack->nStackSize = nSize;}// 车辆信息carinfo 入栈lpCarStackvoid Push( LPTCARSTACK &lpCarStack, TCARINFORMATION carinfo ) {lpCarStack->nTop++;lpCarStack->lpCarInformation[lpCarStack->nTop] = carinfo;}// 车辆信息从栈lpCarStack 中弹出并存入carinfovoid Pop( LPTCARSTACK &lpCarStack, TCARINFORMATION &carinfo ) {carinfo = lpCarStack->lpCarInformation[lpCarStack->nTop];lpCarStack->nTop--;}// 若栈lpCarstack 空,返回TRUE;否则,返回FALSEBOOL IsStackEmpty( LPTCARSTACK lpCarStack ){return lpCarStack->nTop == -1;}// 若栈lpStackFull 满,返回TRUE;否则,返回FALSEBOOL IsStackFull( LPTCARSTACK lpCarStack ){return lpCarStack->nTop == ( lpCarStack->nStackSize - 1 );}// 销毁栈lpCarStack,将指针lpCarStack 置为NULLvoid DestroyStack( LPTCARSTACK &lpCarStack ){free( lpCarStack->lpCarInformation );free( lpCarStack );lpCarStack = NULL;}typedef struct carnode // 链队结点信息{TCARINFORMATION carinfo; // 车辆信息struct carnode *lpNext; // 指向下一个元素的指针} TCARNODE, *LPTCARNODE;typedef struct carqueue // 链队{LPTCARNODE lpHead; // 头结点LPTCARNODE lpRear; // 指向当前队尾的指针int nEffectiveSize; // 当前队中元素个数} TCARQUEUE, *LPTCARQUEUE;// 初始化链队lpCarQueuevoid InitQueue( LPTCARQUEUE &lpCarQueue ){lpCarQueue = ( LPTCARQUEUE ) malloc( sizeof( TCARQUEUE ) ); lpCarQueue->lpHead = ( LPTCARNODE) malloc( sizeof( TCARNODE ) ); lpCarQueue->lpHead->lpNext = NULL;lpCarQueue->lpRear = lpCarQueue->lpHead;lpCarQueue->nEffectiveSize = 0;}// 车辆信息carinfo 入队lpCarQueuevoid EnQueue( LPTCARQUEUE &lpCarQueue, TCARINFORMATION carinfo ){LPTCARNODE lpCarNode = ( LPTCARNODE ) malloc( sizeof( carnode ) );lpCarNode->carinfo = carinfo;lpCarNode->lpNext = NULL;lpCarQueue->lpRear->lpNext = lpCarNode;lpCarQueue->lpRear = lpCarQueue->lpRear->lpNext;lpCarQueue->nEffectiveSize++;}// 队头元素从链队lpCarQueue 中出队并存入carinfovoid DeQueue( LPTCARQUEUE &lpCarQueue, TCARINFORMATION &carinfo ){LPTCARNODE lpTemp = lpCarQueue->lpHead->lpNext;carinfo = lpTemp->carinfo;lpCarQueue->lpHead->lpNext = lpTemp->lpNext;free( lpTemp );lpCarQueue->nEffectiveSize--;}// 若链队lpCarQueue 为空,返回TRUE;否则,返回FALSEBOOL IsQueueEmpty( LPTCARQUEUE lpCarQueue ){return lpCarQueue->nEffectiveSize == 0;}// 销毁链队lpCarQueuevoid DestroyQueue( LPTCARQUEUE &lpCarQueue ){LPTCARNODE lpNextCarNode = NULL;for ( LPTCARNODE lpCarNode = lpCarQueue->lpHead; lpCarNode != NULL; lpCarNode = lpNextCarNode ){lpNextCarNode = lpCarNode->lpNext;free( lpCarNode );}free( lpCarQueue );lpCarQueue = NULL;}// 将字符串时间格式转换为数字(分钟)格式,例如12:36 将被转换为756 ( 12 * 60 + 36 )int ConvertTimeFormat( char *lpTime ){int nHour = 0;int nMinute = 0;sscanf( lpTime, "%d:%d", &nHour, &nMinute );return nHour * 60 + nMinute;}// 根据在停车场内的停留时间nContinuanceMinutes (分钟)计算费用double CalculateExpense( int nContinuanceMinutes ){return nContinuanceMinutes * ( 5.0 / 60 );}int main( void ){setcolor();int nParkCapability = 0; // 停车场容量putchar( '\n' );printf( "请输入停车场容量:" );scanf( "%d", &nParkCapability );LPTCARSTACK lpCarStack = NULL; // 停车场,用栈模拟豫InitStack( lpCarStack, nParkCapability );LPTCARQUEUE lpCarQueue = NULL; // 便道,用链队模拟InitQueue( lpCarQueue );char cCommandType = NULL; // 命令类型char szUserInput[128] = { NULL }; // 用户输入do{ClearScreen();setcolor();putchar( '\n' );puts( "--------------------" );puts( "[命令类型]" );puts( "A - 车辆到达" );puts( "D - 车辆离开" );puts( "E - 停止输入" );puts( "O - 显示当前停车场和便道使用情况" );putchar( '\n' );puts( "例:" );puts( "A,豫A1234,14:26" );puts( "D,豫A1234,16:51" );puts( "E" );puts( "O" );putchar( '\n' );printf( "请输入命令:" );scanf( "%s", szUserInput );puts( "--------------------" );char szCarInformation[128] = { NULL };sscanf( szUserInput, // 将命令类型与车辆信息分开存放"%c,%s",&cCommandType, // 用户输入的前半部分,即命令类型szCarInformation // 用户输入的后半部分,即车辆信息);char *lpCommaLocation = NULL; // 车辆信息字符串中的逗号位置for ( lpCommaLocation = szCarInformation; *lpCommaLocation != '\0'; lpCommaLocation++ ) {if ( *lpCommaLocation == ',' ){break;}}*lpCommaLocation = '\0';TCARINFORMATION carinfo = { NULL }; // 存储本次用户输入的车辆信息strcpy( carinfo.szRegistrationMark, szCarInformation );if ( cCommandType == 'A' ){strcpy( carinfo.szArrivalTime, lpCommaLocation + 1 );if ( FALSE == IsStackFull( lpCarStack ) ){strcpy( carinfo.szEntranceTime, carinfo.szArrivalTime );Push( lpCarStack, carinfo );printf( "已进入停车场第%d 个车位\n",lpCarStack->nTop + 1);printf( "车牌号:\t\t%s\n", carinfo.szRegistrationMark );printf( "进入时间:\t%s\n", carinfo.szEntranceTime );puts( "是否收费:\t是" );}else{EnQueue( lpCarQueue, carinfo );printf( "停车场已满,已停放在便道的第%d 个车位\n",lpCarQueue->nEffectiveSize);printf( "车牌号:\t\t%s\n", carinfo.szRegistrationMark );printf( "停放时间:\t%s\n", carinfo.szArrivalTime );puts( "是否收费:\t否" );}}else if ( cCommandType == 'D' ){strcpy( carinfo.szDepartureTime, lpCommaLocation + 1 );LPTCARSTACK lpTempCarStack = NULL;InitStack( lpTempCarStack, nParkCapability );TCARINFORMATION carinfoOut = { NULL };BOOL bIsCarFound = FALSE;while ( FALSE == IsStackEmpty( lpCarStack ) ){Pop( lpCarStack, carinfoOut );if ( 0 != strcmp( carinfoOut.szRegistrationMark, carinfo.szRegistrationMark ) ) {Push( lpTempCarStack, carinfoOut );}else{bIsCarFound = TRUE;break;}}while ( FALSE == IsStackEmpty( lpTempCarStack ) ){TCARINFORMATION tempcarinfo = { NULL };Pop( lpTempCarStack, tempcarinfo );Push( lpCarStack, tempcarinfo );}if ( FALSE == bIsCarFound ){printf( "车牌号为%s 的车未进入停车场.\n", carinfo.szRegistrationMark ); Pause( "--------------------\n按任意键输入下一条信息...\n" );continue;}strcpy( carinfoOut.szDepartureTime, carinfo.szDepartureTime );int nEntranceTime = ConvertTimeFormat( carinfoOut.szEntranceTime );int nDepartureTime = ConvertTimeFormat( carinfoOut.szDepartureTime );int nContinuanceMinutes = nDepartureTime - nEntranceTime;printf( "计费时段:\t%s - %s (共%d 分钟)\n",carinfoOut.szEntranceTime,carinfoOut.szDepartureTime,nContinuanceMinutes);double rExpense = CalculateExpense( nContinuanceMinutes );printf( "应交纳的费用:\t%.1lf 元\n", rExpense );if ( FALSE == IsQueueEmpty( lpCarQueue ) ){TCARINFORMATION tempcarinfo = { NULL };DeQueue( lpCarQueue, tempcarinfo );strcpy( tempcarinfo.szEntranceTime, carinfoOut.szDepartureTime ); Push( lpCarStack, tempcarinfo );puts( "--------------------" );printf( "停放在便道的第1 个车位,车牌号为%s 的车已进入停车场\n", tempcarinfo.szRegistrationMark);}}else if ( cCommandType == 'E' ){puts( "********************" );puts( " 姓名:肖熊\n" );puts( "学号:200813080245 \n" );puts( "********************" );break;}else if ( cCommandType == 'O' ){ClearScreen();setcolor();putchar( '\n' );puts( "[停车场使用情况]\n" );puts( "[车位]\t[车牌号]\t[到达时间]\t[进入(开始计费)时间]\n");for ( int i = 0; i <= lpCarStack->nTop; i++ ){printf( "%d\t%s\t\t%s\t\t%s\n",i + 1,lpCarStack->lpCarInformation[i].szRegistrationMark,lpCarStack->lpCarInformation[i].szArrivalTime,lpCarStack->lpCarInformation[i].szEntranceTime);}putchar( '\n' );putchar( '\n' );putchar( '\n' );puts( "[便道使用情况]\n" );puts( "[车位]\t[车牌号]\t[到达时间]\t[进入(开始计费)时间]\n");int nNum = 0;for ( LPTCARNODE lpCarNode = lpCarQueue->lpHead->lpNext;lpCarNode != NULL; lpCarNode = lpCarNode->lpNext ){nNum++;printf( "%d\t%s\t\t%s\t\t%s\n",nNum,lpCarNode->carinfo.szRegistrationMark,lpCarNode->carinfo.szArrivalTime,lpCarNode->carinfo.szEntranceTime);}putchar( '\n' );}else{puts( "输入信息有误.第一个字符只能为'A' 或'D' 或'E' 或'O' (区分大小写)." ); }Pause( "--------------------\n按任意键输入下一条信息.\n" );} while ( TRUE );DestroyStack( lpCarStack );DestroyQueue( lpCarQueue );Pause( "\n按任意键退出程序...\n" );return 0;}。