題目内容:
停車場模拟:利用棧實作單道停車場,也就是該停車場先進來的車隻能最後出,如果某輛車想出車道,必須先把其前面的車先退出棧,等該車開走,再将之前的車壓入棧。
輸入檔案如附件檔案中data.txt所示,其中格式如:“COOLONE arrives”,表示COOLONE的車到達;輸出如檔案outpu.txt所示,其中格式為:“COOLONE was moved 0 times while it was here”,表示該車在離開之前沒有移動過。
思路分析:
單道停車場,存在着挪車回原位的過程,如果多一個挪車場(假想)會更友善操作,是以本題采用的解法是雙棧法。
注意:思路和代碼僅供借鑒,此貼隻作紀念
核心代碼如下:
# include <stdio.h>
# include <malloc.h>
# include <string.h>
// 函數結果狀态代碼
# define TRUE 1
# define FALSE 0
# define OK 1
# define ERROR 0
# define INFEASIBLE -1
# define OVERFLOW -2
# define MAXSIZE 5 //總共的車位數
#define BUFF_LEN 1024 //每行的長度均為15 前7個字元是汽車牌
//Status 是函數的類型,其值是函數結果狀态代碼
typedef int Status;
typedef char SElemType;
//車
typedef struct {
char name[8];
int movedtime; //移動次數
}Car;
//停車場 //這裡采用順序棧實作
typedef struct {
Car* base; //棧底指針
Car* top; //棧頂指針
int stackSize; //棧可用的最大容量
}P_SqStack;
Status initParkLot(P_SqStack *p); //建立停車場或臨時車場
Status initCar(Car* car); //初始化汽車
Car Pop(P_SqStack *p); //彈出停車場的車或者彈出臨時車場的車,并傳回汽車
Status Push(P_SqStack *p, Car car); //把車停入停車場或臨時車場
char * left(char *dst, char *src, int n); //從字元串的左邊截取n個字元
//建立停車場或臨時車場
Status initParkLot(P_SqStack *p) {
p->base = (Car*)malloc(MAXSIZE * sizeof(Car));
if (!p ->base) {
exit(OVERFLOW);
}
p->top = p->base; //棧頂指針指向棧底指針
p->stackSize = MAXSIZE;
return OK;
}
//汽車的初始化
Status initCar(Car* car) {
for(int i=0;i<8;i++){
car->name[i] ="";
}
car->movedtime = 0;
return OK;
}
//彈出停車場的車或者彈出臨時車場的車,并傳回汽車
Car Pop(P_SqStack *p) {
Car car;
//關于棧空的判斷,寫在了主函數裡面
p->top--;
car = *p->top;
return car;
}
//把車停入停車場或臨時車場
Status Push(P_SqStack *p, Car car) {
*p->top = car;
p->top++;
return OK;
}
//p->top = (Car*)malloc(sizeof(Car)); //這裡絕對不能配置設定,不然會出現沖突,因為在初始化時,top已經指向了一片空間,不能再多指向一個空間
//從字元串的左邊截取n個字元
char * left(char *dst, char *src, int n)
{
char *p = src;
char *q = dst;
int len = strlen(src);
if (n > len) n = len;
while (n--) *(q++) = *(p++);
*(q++) = '\0'; //補回這個字元串的結束符,防止系統沒有補'\0'導緻出bug
return dst;
}
//汽車move的次數,取決于它自己離開前,在它底下的車有多少台離開了
int main() {
//建立棧結構 停車場和汽車都要建立
P_SqStack pInt;
P_SqStack pTemp;
initParkLot(&pInt);
initParkLot(&pTemp);
FILE* file;
FILE* filewrite = fopen("output.txt", "w+"); //寫出到output.txt
char line[BUFF_LEN] = { 0 };
file = fopen("data.txt","r");
//IO流一行一行地讀取
while (fgets(line,BUFF_LEN,file) != NULL)
{
Car car;
initCar(&car);
char temp[10] = ""; //temp[]絕不能開到[7],因為後面要補一個'\0'表示結束
if (strstr(line, "arrives")) {//有汽車到達
left(temp, line, 7);
for (int i = 0; i < 8;i++) {
car.name[i] = temp[i];
}
if ((pInt.top - pInt.base) != MAXSIZE) {
//此時停車場車位沒有滿
Push(&pInt, car);
}
else
{//Sorry PORSCHE, the lot is full
printf("Sorry %s, the lot is full\n", car.name);
//輸出到output.txt文本檔案
fprintf(filewrite, "Sorry %s, the lot is full\n", car.name);
continue;
}
}
if (strstr(line, "departs")) {
left(temp, line, 7);
//有汽車停在停車場裡,才能彈出汽車
if (pInt.base != pInt.top) {
car = Pop(&pInt);
while (strcmp(car.name, temp) != 0 && pInt.base != pInt.top) {
//循環條件
//把排在要離開的車前面的所有車移入臨時車場
//還要注意停車場不能為空才可以進行
car.movedtime += 1;
Push(&pTemp, car);
//繼續進行挪車,用一個car來接受,便于比較
car = Pop(&pInt);
}
}
//跳出while循環時,此時car的名字就是要離開的車的名字
//COOLONE was moved 0 times while it was here
printf("%s was moved %d times while it was here\n", car.name, car.movedtime);
fprintf(filewrite, "%s was moved %d times while it was here\n", car.name, car.movedtime);
Car cartemp;
initCar(&cartemp);
//将臨時車場剩餘的所有汽車複原回停車場
while (pTemp.base != pTemp.top)
{
cartemp = Pop(&pTemp);
Push(&pInt, cartemp);
}
}
}
//列印出最後停留在停車場裡沒有出去的汽車的資訊
//printStack(pInt);
while (pInt.base != pInt.top) {
pInt.top--;
printf("%s was moved %d times while it was here\n", pInt.top->name, pInt.top->movedtime);
fprintf(filewrite, "%s was moved %d times while it was here\n", pInt.top->name, pInt.top->movedtime);
}
//關閉檔案流
fclose(filewrite);
return 0;
}