您的位置:首页 > 理论基础 > 数据结构算法

【数据结构】使用栈和队列判断字符串是否是回文

2017-10-22 17:22 645 查看

原题目:

  假设称正读和反读都相同的字符序列为“回文”,例如,‘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;
}


运行结果:



上图的输出界面有点不符合常规,是因为直接将整个字符串输出了。这里可以进一步改进。就不讨论了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐