实验三:栈与队列的应用

实验题目

1:依据顺序栈存储结构的定义如下:(利用以下的常用操作设计算法并实现完成2、3题)

#define  MAXSIZE  100
typedef char SElemType;
typedef struct
{
		SElemType   *base;
		SElemType   *top;
		int stacksize;
}SqStack;
//调试并测试常用操作如下:
int InitStack( SqStack &S )
int StackEmpty( SqStack S )
int StackLength( SqStack S )
int Push( SqStack &S, SElemType e)  
int Pop( SqStack &S, SElemType &e)  

2:设单链表中存放n个字符,试设计一个算法,判断该字符串是否中心对称。
3:利用栈来实现算术表达式求值的算法。** 程序运行时,输入合法的算术表达式(中间值及最终结果要在0~9之间,可以包括加减乘除和括号),便可输出相应的计算结果。**

头文件

#ifndef _STACK_H_
#define _STACK_H_

#include <iostream>
#include <cstdlib>
#include <stdio.h>

#define  MAXSIZE  100
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef char SElemType;
using namespace std;

typedef struct//栈结构体
{
		SElemType   *base;
		SElemType   *top;
		int stacksize;
}SqStack;


typedef struct LNode//单链表结构体
{
     SElemType   data;
     struct LNode  *next;
}LNode,*LinkList;

//初始化栈
Status InitStack(SqStack &S){
    S.base = new SElemType [MAXSIZE];
    if (!S.base)
        exit(OVERFLOW);
    S.top = S.base;
    S.stacksize = MAXSIZE;
    return OK;
}

//判断栈满栈空
Status StackEmpty(SqStack S){
    if(S.top - S.base == S.stacksize)
        return ERROR;
    else return OK;
}

//求栈长
int StackLength(SqStack S){
    return (S.top - S.base);
}

//入栈函数
Status Push(SqStack &S,SElemType e){
    if(StackEmpty(S)){
        *S.top++ = e;
        return OK;
    }
    else return ERROR;
}

//出栈函数
Status Pop(SqStack &S,SElemType &e){
    if(S.top == S.base)
        return ERROR;
    e = *--S.top;
    return OK;
}

//取栈顶元素
SElemType GetTop(SqStack S){
    if(S.top != S.base){
        return *(S.top-1);
    }
    else return ERROR;
}

//创建单链表
void CreateList_L(LinkList &L,int n){
     L=new LNode;
     L->next=NULL; //先建立一个带头结点的单链表
    LinkList p;
   // InitList_L(L);
      for(int i=n;i>0;--i){
        p=new LNode; //生成新结点
           cin>>p->data; //输入元素值
        p->next=L->next;L->next=p; 	//插入到表头
     }
}
//打印单链表
void PrintList_L(LinkList &L){
    LinkList p=L->next;
    while(p) {
        cout<<p->data<<endl;
        p=p->next;
    }
}

//单链表删除元素
Status ListDelete(LinkList &L,int i){

    LinkList p=L,q;
    int j=0;
    while((p->next) && (j<i-1)){
            p=p->next;
            ++j;
    }
    if(!(p->next) || (j>i-1))
            return ERROR;
        q=p->next;
        p->next=q->next;
        delete q;
        return OK;
}
//获取单链表元素值
Status GetElem(LinkList L,int i,SElemType &e){
    LinkList p=L->next;
    int j=1;
    while (p && j<i){
        p=p->next;
        ++j;
    }
    if(!p || j>i)
        return ERROR;
    e=p->data;
    return OK;
}

#endif // _STACK_H_

main.cpp

#include "stack.h"

Status TestStack(SqStack &S,SElemType &e);
int Center(LinkList &L,SqStack &S);
char EvaluateExpression ();
SElemType Precede(SElemType t1,SElemType t2);
Status In(SElemType c);
SElemType Operate(SElemType a,SElemType theta,SElemType b);

int main()
{
    LinkList L;
    SqStack S;
    SElemType e;
    //SqStack *p = &S;

    printf("第1题\n");
    TestStack(S,e);
    //cout << "" << endl;

    printf("第2题\n");
    printf("请输入要判断中心对称的字符串,长度为5\n");
    CreateList_L(L,5);
    ListDelete(L,3);
    //PrintList_L(L);
    if(Center(L,S))
        printf("该字符串不是中心对称的字符串\n");
    else
		printf("该字符串是中心对称的字符串\n");


    printf("第3题\n");
    cout<<"请输入算术表达式,并以#结束."<<endl;
    cout<<EvaluateExpression()<<endl;


    return 0;
}

//栈基础测试函数
Status TestStack(SqStack &S,SElemType &e){
    InitStack(S);
    cout << "当前栈的长度为:" ;
    cout << StackLength(S) << endl;
    cout << "请输入将要入栈的元素:" << endl;
    cin >> e;
    Push(S,e);
    cout << "当前栈的长度为:" ;
    cout << StackLength(S) << endl;
    Pop(S,e);
    cout << "出栈:" ;
    cout << e <<endl;
    cout << "当前栈的长度为:" ;
    cout << StackLength(S) << endl;
    return OK;
}

//判断是否中心对称
int Center(LinkList &L,SqStack &S){
    int i;
    SElemType e;
    for(i=1;i<=4;i++){
        GetElem(L,i,e);
        if(e == GetTop(S)){
            Pop(S,e);
        }else{
            Push(S,e);
        }
    }
    if(StackLength(S))
        return 1;
    return 0;
    //GetElem(LinkList L,int i,SElemType &e)
}

char EvaluateExpression() {//算术表达式求值的算符优先算法,设OPTR和OPND分别为运算符栈和操作数栈

	SqStack OPTR, OPND;
	char ch, theta, a, b, x;

	InitStack(OPND); //初始化OPND操作数栈
	InitStack(OPTR); //初始化OPTR运算符栈
	Push(OPTR, '#'); //将表达式起始符“#”压入OPTR栈

	scanf("%c",&ch);
	while (ch != '#' || (GetTop(OPTR) != '#')) //表达式没有扫描完毕或OPTR的栈顶元素不为“#”
	{
		if (!In(ch)) {
			Push(OPND, ch);
			scanf("%c",&ch);
		} //ch不是运算符则进OPND栈
		else
			switch (Precede(GetTop(OPTR), ch)) //比较OPTR的栈顶元素和ch的优先级
			{
			case '<': //栈顶元素优先级低
				Push(OPTR, ch);
				scanf("%c",&ch); //当前字符ch压入OPTR栈,读入下一字符ch
				break;
			case '>':
				Pop(OPTR, theta); //弹出OPTR栈顶的运算符
				Pop(OPND, b);
				Pop(OPND, a); //弹出OPND栈顶的两个运算数
				Push(OPND, Operate(a, theta, b)); //将运算结果压入OPND栈
				break;
			case '=': //OPTR的栈顶元素是“(”且ch是“)”
				Pop(OPTR, x);
				scanf("%c",&ch); //弹出OPTR栈顶的“(”,读入下一字符ch
				break;
			} //switch
	} //while
	return GetTop(OPND); //OPND栈顶元素即为表达式求值结果
}

Status In(SElemType c)// 应在前面有定义typedef char SElemType;
 { // 判断c是否为运算符
    switch(c)
    {
        case'+':return true;break;
        case'-':return true;break;//……//补充完整
        case'*':return true;break;
        case'/':return true;break;
        case'(':return true;break;
        case')':return true;break;
        case'#':return OVERFLOW;break;
        default:return false;
    }
 }

 SElemType Precede(SElemType t1,SElemType t2)
 { //根据教材表3.1,判断两个运算符的优先关系
    SElemType f;
    switch(t2)
    {
        case '+':
            if(t1=='('||t1=='#')
                f='<';
            else
                f='>';
            break;
        case '-':
            if(t1=='('||t1=='#')
                f='<';
            else
                f='>';
            break;//……//补充完整
        case '*':
            if(t1=='*' || t1=='/' || t1==')')
                f='>';
            else
                f='<';
            break;
        case '/':
            if(t1=='*' || t1=='/' || t1==')')
                f='>';
            else
                f='<';
            break;
        case '(':
            f='<';
            break;
        case ')':
            if(t1=='(')
                f='=';
            else
                f='>';
            break;
        case '#':
            if(t1=='#')
                f='=';
            else
                f='>';
            break;
    }
  return f;
}

SElemType Operate(SElemType a,SElemType theta,SElemType b)
 {
    SElemType c;
    a=a-48;
    b=b-48;
    switch(theta)
    {
        case'+':c=a+b+48;
                 break;//……//补充完整
        case'-':c=a-b+48;
                break;
        case'*':c=a*b+48;
                break;
        case'/':c=a/b+48;
                break;
    }
    return c;
 }

实验运行结果

1题
当前栈的长度为:0
请输入将要入栈的元素:
1
当前栈的长度为:1
出栈:1
当前栈的长度为:02题
请输入要判断中心对称的字符串,长度为5
1
2
3
4
5
该字符串不是中心对称的字符串
第3题
请输入算术表达式,并以#结束.
1+3/3+(2*3)-2#
6

Process returned 0 (0x0)   execution time : 37.894 s
Press any key to continue.

1题
当前栈的长度为:0
请输入将要入栈的元素:
1
当前栈的长度为:1
出栈:1
当前栈的长度为:02题
请输入要判断中心对称的字符串,长度为5
1
2
3
2
1
该字符串是中心对称的字符串
第3题
请输入算术表达式,并以#结束.
1+3*2-3/3#
6

Process returned 0 (0x0)   execution time : 28.153 s
Press any key to continue.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值