【資料結構】使用棧和佇列判斷字串是否是迴文
阿新 • • 發佈:2019-01-30
原題目:
假設稱正讀和反讀都相同的字元序列為“迴文”,例如,‘abba’和‘abcba’是迴文,‘abcde’和‘ababab’則不是迴文。試寫一個演算法判別讀入的一個以‘@’為結束符的字元序列是否是“迴文”。
原始碼:
// *.cpp: 定義控制檯應用程式的入口點。 #include <iostream> using namespace std; #define STACK_INIT_SIZE 100 #define STACKINCREASE 10 #define SElemType char #define QElemType char #define Status int #define OK 1 #define OVERFLOW -1 #define ERROR 0 typedef struct QNode { QElemType data; struct QNode *next; }QNode, *QueuePtr; typedef struct { QueuePtr front; //對頭指標 QueuePtr rear; //隊尾指標 }LinkQueue; //構造空佇列Q Status InitQueue(LinkQueue &Q) { Q.front = Q.front = (QueuePtr)malloc(sizeof(QNode)); if (!Q.front) return OVERFLOW; Q.front->next = NULL; return OK; } //元素e插入佇列 Status EnQueue(LinkQueue &Q, QElemType e) { QueuePtr p, q; p = new QNode; q = new QNode; if (!p) return OVERFLOW; p->data = e; p->next = NULL; if (Q.front->next == NULL) { Q.front->next = p; Q.rear = p; } else { q = Q.front; while (q->next->next != NULL) { q = q->next; } q->next->next = p; Q.rear = p; } return OK; } //刪除Q的隊頭元素 Status DeQueue(LinkQueue &Q, QElemType &e) { QueuePtr p; if (Q.front == Q.rear) return ERROR; p = Q.front->next; e = p->data; Q.front->next = p->next; if (Q.rear == p) Q.rear = Q.front; delete(p); return OK; } typedef struct { SElemType *base; SElemType *top; int stacksize; }SqStack; //構造空棧S Status InitStack(SqStack &S) { S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)); if (!S.base) return OVERFLOW; S.top = S.base; S.stacksize = STACK_INIT_SIZE; return OK; } //入棧操作 Status Push(SqStack &S, SElemType e) { if (S.top - S.base >= S.stacksize) { //棧滿,追加空間 S.base = (SElemType *)realloc(S.base, (S.stacksize + STACKINCREASE) * sizeof(SElemType)); if (!S.base) return ERROR; //儲存空間分配失敗 S.top = S.base + S.stacksize; S.stacksize += STACKINCREASE; } *S.top = e; S.top++; return OK; } //出棧操作 Status Pop(SqStack &S, SElemType &e) { if (S.top == S.base) return ERROR; e = *--S.top; return OK; } //判斷是否是迴文,若是,返回OK,否則,返回ERROR Status IsPalindrome(char p[]) { LinkQueue Q; SqStack S; if (!InitStack(S)) return ERROR; if (!InitQueue(Q)) return ERROR; SElemType e1; QElemType e2; int i = 0; while (p[i]) { //將輸入的字串p輸入到棧和佇列中 Push(S, p[i]); //同時i記錄字元個數 EnQueue(Q, p[i++]); } for (i; i>0; i--) { //將字元分別從棧和佇列中取出 Pop(S, e1); DeQueue(Q, e2); if (e1 != e2) //兩個字元不相等,返回錯誤 return ERROR; } return OK; } int main() { char p[80], e; cout << "請輸入一串字元:"; cin >> p; if (IsPalindrome(p)) cout << p << "是迴文字串!\n"; else cout << p << "不是迴文字串!" << endl; return 0; }
執行結果圖:
另外:
原題目要求的是一個以“@”為結束符的字串,然而上述程式碼不是這樣實現的。如果想按照原題目要求做,只需要將 IsPalindrome(char p[])函式中的第一個while循壞中的迴圈條件改為(p[i]!='@') 即可。
源部分程式碼:
Status IsPalindrome(char p[]) { LinkQueue Q; SqStack S; if (!InitStack(S)) return ERROR; if (!InitQueue(Q)) return ERROR; SElemType e1; QElemType e2; int i = 0; while (p[i]!='@') { //【改變此處的迴圈終止條件即可!!!】 Push(S, p[i]); //同時i記錄字元個數 EnQueue(Q, p[i++]); } for (i; i>0; i--) { //將字元分別從棧和佇列中取出 Pop(S, e1); DeQueue(Q, e2); if (e1 != e2) //兩個字元不相等,返回錯誤 return ERROR; } return OK; }
執行結果:
上圖的輸出介面有點不符合常規,是因為直接將整個字串輸出了。這裡可以進一步改進。就不討論了。