- 说明:这是武汉理工大学计算机学院计科专业【数据结构】课程的实验:使用栈和队列判断字符串是否是回文
- >>点击查看武汉理工大学计算机专业课程资料汇总
- >>点击查看WUTer计算机专业实验汇总
- 谨记:纸上得来终觉浅,绝知此事要躬行。
原题目:
假设称正读和反读都相同的字符序列为“回文”,例如,‘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;
}
运行结果:
上图的输出界面有点不符合常规,是因为直接将整个字符串输出了。这里可以进一步改进。就不讨论了。