数据结构实验课:实验三、栈的实现及应用

一、实验目的
1.掌握栈的存储表示和实现
2.掌握栈的基本操作实现。
3.掌握栈在解决实际问题中的应用。
二、实验要求
问题描述:设计一个程序,演示用算符优先法对算术表达式求值的过程。利用算符优先关系,实现对算术四则混合运算表达式的求值。
(1)输入的形式:表达式,例如2*(3+4)#
包含的运算符只能有’+’ 、’-’ 、’’ 、’/’ 、’(’、 ‘)’,“#”代表输入结束符;
(2)输出的形式:运算结果,例如2
(3+4)=14;
(3)程序所能达到的功能:对表达式求值并输出。
三、解题参考思路
为了实现用栈计算算数表达式的值,需设置两个工作栈:用于存储运算符的栈opter,以及用于存储操作数及中间结果的栈opnd。
算法基本思想如下:
(1)首先将操作数栈opnd设为空栈,而将’#‘作为运算符栈opter的栈底元素,这样的目的是判断表达式是否求值完毕。
(2)依次读入表达式的每个字,表达式须以’#‘结,读入字符若是操作数则入栈opnd,读入字符若是运算符,则将此运算符c与opter的栈顶元素top比较优先级后执行相应的操作,具体操作如下:
(i)若top的优先级小于c,即top<c,则将c直接入栈opter,并读入下一字符赋值给c;
(ii)若top的优先级等于c,即top=c,则弹出opter的栈顶元素,并读入下一字符赋值给c,这一步目的是进行括号操作;
(iii)若top优先级高于c,即top>c,则表明可以计算,此时弹出opnd的栈顶两个元素,并且弹出opter栈顶的的运算符,计算后将结果放入栈opnd中。直至opter的栈顶元素和当前读入的字符均为’#’,此时求值结束。
算符间的优先关系如下表所示(表来源:严蔚敏《数据结构》):

表中需要注意的是θ1为opter的栈顶元素,θ2为从表达式中读取的操作符,此优先级表可以用二维数组实现。
图例:

比较算符优先关系代码示例:
int getIndex(char theta) //获取theta所对应的索引
{
int index = 0;
switch (theta)
{
case ‘+’:
index = 0;
break;
case ‘-’:
index = 1;
break;
case ‘*’:
index = 2;
break;
case ‘/’:
index = 3;
break;
case ‘(’:
index = 4;
break;
case ‘)’:
index = 5;
break;
case ‘#’:
index = 6;
default:break;
}
return index;
}

char getPriority(char theta1, char theta2) //获取theta1与theta2之间的优先级
{
const char priority[][7] = //算符间的优先级关系
{
{ ‘>’,’>’,’<’,’<’,’<’,’>’,’>’ },
{ ‘>’,’>’,’<’,’<’,’<’,’>’,’>’ },
{ ‘>’,’>’,’>’,’>’,’<’,’>’,’>’ },
{ ‘>’,’>’,’>’,’>’,’<’,’>’,’>’ },
{ ‘<’,’<’,’<’,’<’,’<’,’=’,‘0’ },
{ ‘>’,’>’,’>’,’>’,‘0’,’>’,’>’ },
{ ‘<’,’<’,’<’,’<’,’<’,‘0’,’=’ },
};

int index1 = getIndex(theta1);
int index2 = getIndex(theta2);
return priority[index1][index2];
}
四、实验任务
认真阅读与理解实验内容的具体要求,参考教材相关章节,结合实验内容的要求,编写实验程序并上机调试与测试,完成实验报告的撰写。

(已改)代码如下

#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define MAXSIZE 100 // 存储空间初始分配量
typedef int Status;
typedef struct
{
    
    
        int data[MAXSIZE];
        int top; // 用于栈顶指针
}opndStack;

typedef struct
{
    
    
        char data[MAXSIZE];
        int top; // 用于栈顶指针
}opterStack;

//====================================================================
int getIndex(char theta)   //获取theta所对应的索引
{
    
    
    int index = 0;
    switch (theta)
    {
    
    
	    case '+':
	        index = 0;
	        break;
	    case '-':
	        index = 1;
	        break;
	    case '*':
	        index = 2;
	        break;
	    case '/':
	        index = 3;
	        break;
	    case '(':
	        index = 4;
	        break;
	    case ')':
	        index = 5;
	        break;
	    case '#':
	        index = 6;
	    default:break;
    }
    return index;
}

//====================================================================

char getPriority(char theta1, char theta2)   //获取theta1与theta2之间的优先级
{
    
    
    const char priority[][7] =     //算符间的优先级关系
    {
    
    
        {
    
     '>','>','<','<','<','>','>' },
        {
    
     '>','>','<','<','<','>','>' },
        {
    
     '>','>','>','>','<','>','>' },
        {
    
     '>','>','>','>','<','>','>' },
        {
    
     '<','<','<','<','<','=','0' },
        {
    
     '>','>','>','>','0','>','>' },
        {
    
     '<','<','<','<','<','0','=' },
    };

    int index1 = getIndex(theta1);
    int index2 = getIndex(theta2);
    return priority[index1][index2];
}

//====================================================================

Status InitopndStack(opndStack *S)//建立opnd空栈
{
    
    
    S->top=-1;
    return OK;
}

Status InitopterStack(opterStack *S)//建立opter空栈
{
    
    
    S->top=-1;
    return OK;
}

//====================================================================

Status Pushnd(opndStack *S,int n)//入栈
{
    
    
    if(S->top== MAXSIZE-1)
    {
    
    
        return ERROR;
    }
    S->top++;//
    S->data[S->top]=n;
    return OK;
}

Status Pushter(opterStack *S,char n)
{
    
    
    if(S->top== MAXSIZE-1)
    {
    
    
        return ERROR;
    }
    S->top++;//
    S->data[S->top]=n;
    return OK;
}

//=========================================================

Status Popnd(opndStack *S,int *n)//出栈 并返回到 n 中
{
    
    
    if(S->top==-1)
        return ERROR;
    *n=S->data[S->top];
    (S->top)--;
    return OK;
}

Status Popter(opterStack *S,char *n)
{
    
    
    if(S->top==-1)
        return ERROR;
    *n=S->data[S->top];
    S->top--;
    return OK;
}

//=======================================================

signed int calculate(int x1,int x2,char c)
{
    
    
    switch(c)
    {
    
    
    case '+':
        return (x1+x2);
    case '-':
        return (x1-x2);
    case '*':
        return (x1)*(x2);
    case '/':
        return (x1)/(x2);
    default:
        return 0;
    }
    return 0;
}

//======================================================

int isdigit(char c)//判断是否为操作数
{
    
    
    if(c<='9'&& c>='0')
        return 1;
    else
        return 0;
}

int ischar(char c)//判断是否为运算符
{
    
    
    switch(c)
    {
    
    
    case '+':
    case '-':
    case '*':
    case '/':
    case '(':
    case ')':
    case '#':
        return 1;
    default:
        return 0;
    }
    return 0;

}
//=========================================================

void input(char s[])  //输入表达式 存入s[]数组中。
{
    
    
    char c;
    int i = 0;
    while(c!='#')
    {
    
    
        while((c=getchar())==' ');//跳过所有空格进行c的输入
        s[i++]=c;
    }
    return ;
}

//==========================================================

int calculateall()
{
    
    
    char c,s[100]={
    
    0},k;
    int x1,x2,i=0;
    int n=0;
    opndStack opnd;
    opterStack opter;
    InitopndStack(&opnd); //空栈
    InitopterStack(&opter);
    Pushter(&opter,'#');

    input(s);

    while(s[i]!='\0')
    {
    
    
        c=s[i];
            if(ischar(c))
            {
    
    
                 switch(getPriority(opter.data[opter.top],c))
                    {
    
    
                    case '<':
                        Pushter(&opter,c);
                        break;
                    case '=':
                        Popter(&opter,&k);//k没有用处 用来满足函数关系而已
                        break;
                    case '>':
                        while(getPriority(opter.data[opter.top],c)=='>')
                        {
    
    
                            Popnd(&opnd,&x1);
                            Popnd(&opnd,&x2);
                            Popter(&opter,&k);
                            x1=calculate(x2,x1,k);
                            Pushnd(&opnd,x1);
                        }
                        if(getPriority(opter.data[opter.top],c)=='<')
                            Pushter(&opter,c);
                        else
                            Popter(&opter,&k);
                        break;
                    default:
                        printf("INPUT ERROR");
                    }
            }
            else
            {
    
    
                Pushnd(&opnd,c-'0');
            }
        ++i;
    }
    Popnd(&opnd,&k);
    return k;
}

//=========================================================
int main()
{
    
    
   int k;
   k=calculateall();
   printf("%d",k);
   return 0;
}

当时自己写的版本(c++)

#include <iostream>
using namespace std;
#include <string>
#define size2 10
#define size1 100
#define erro -1
typedef int iii;
typedef struct
{
    
    
    char *base;
    char *top;
    int size;
} stack2;
typedef struct
{
    
    
    iii * base;
    iii* top;
    int size;
} stack;
void InitStack(stack2 &s)//初始化栈
{
    
    
    s.base=(char*)malloc (size1*sizeof(char));
    if(!s.base)

    {
    
    
        printf("超出界限\n");
        return;

    }
    else

    {
    
    
        s.top=s.base;
        s.size=size1;

    }
}
void InitStack(stack &s)//初始化栈
{
    
    
    s.base=(iii *)malloc (size1*sizeof(iii));
    if(!s.base)

    {
    
    
        printf("超出界限\n");
        return;

    }
    else

    {
    
    
        s.top=s.base;
        s.size=size1;

    }
}
void Insert(stack2 &s,char a) //插入元素
{
    
    
    if(s.top-s.base>=s.size)

    {
    
    
        s.base=(char *)realloc (s.base,(s.size+size1)*sizeof (char));
        if(!s.base)
        {
    
    
            printf("超出界限\n");
            return ;

        }

    }
    *s.top++=a;
}
void Insert2( stack &s,int a)
{
    
    
    if(s.top-s.base>=s.size)

    {
    
    
        s.base=(iii *)realloc (s.base,(s.size+size1)*sizeof (iii));
        if(!s.base)
        {
    
    
            printf("超出界限\n");
            return ;

        }

    }
    *s.top++=a;
}
char Pop(stack2 &s )//删除栈顶元素,并返回栈顶元素
{
    
    
    if(s.top==s.base)

    {
    
    
        printf("栈为空\n");
        return erro;

    }
    else

    {
    
    
        *--s.top;
        return * s.top;

    }
}
int Pop2(stack &s)
{
    
    
    if(s.top==s.base)

    {
    
    
        printf("栈为空\n");
        return erro;//没意义

    }
    else

    {
    
    
        *--s.top;
        return * s.top;

    }
}
void View(stack &s)
{
    
    
    for(int i=1; i<=(s.top-s.base); i++)

    {
    
    
        char k;
        k=*(s.top-i);
        cout<<k<<endl;

    }
}
char GetPop(stack2 &s)
{
    
    
    if(s.top==s.base)

    {
    
    
        printf("栈为空\n");
        return-1;

    }
    else
        return *(s.top-1);
}
int GetPop2(stack &s)
{
    
    
    if(s.top==s.base)

    {
    
    
        printf("栈为空\n");
        return-1;

    }
    else
        return *(s.top-1);
}
char Compare(char q,char r)//比较优先级
{
    
    
    int j[2];
    char str[2];
    char table[7][7]=
    {
    
    
        {
    
    '>','>','<','<','<','>','>'},
        {
    
    '>','>','<','<','<','>','>'},
        {
    
    '>','>','>','>','<','>','>'},
        {
    
    '>','>','>','>','<','>','>'},
        {
    
    '<','<','<','<','<','=','e'},
        {
    
    '>','>','>','>','e','>','>'},
        {
    
    '<','<','<','<','<','e','='}

    };
    str[0]=q;
    str[1]=r;
    for(int i=0; i<2; i++)

    {
    
    
        switch(str[i])
        {
    
    
        case '+':
            j[i]=0;
            break;
        case '-':
            j[i]=1;
            break;
        case '*':
            j[i]=2;
            break;
        case '/':
            j[i]=3;
            break;
        case '(':
            j[i]=4;
            break;
        case ')':
            j[i]=5;
            break;
        case '#':
            j[i]=6;
            break;

        }

    }
    return table[j[0]][j[1]];
}
int Operate (int a,char b,int c)
{
    
    
    switch(b)

    {
    
    
    case '+':
        return a+c;
    case '-':
        return a-c;
    case '*':
        return a*c;
    case '/':
        return a/c;

    }
}
bool Decide(char c)
{
    
    
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='#')
        return true;
    else
        return false;
}
int main()
{
    
    
    stack2 a;
    stack b;//a存储符号,b存储数字
    InitStack(a);
    Insert(a,'#');
    InitStack(b);
    char c;
    c=getchar();
    int temp=0;
    while (c!='#'||GetPop(a)!='#')

    {
    
    
        if(!Decide(c))
        {
    
    
            temp=(temp*10+c-'0');//可支持数位数字
            c=getchar();

        }
        else if(Decide(c))
        {
    
    
            if(temp!=0)
            {
    
    
                Insert2(b,temp);

            }
            temp=0;
            switch(Compare(GetPop(a),c))
            {
    
    
            case '<':
//栈顶元素优先权低
//cout<<"<"<<endl;
                Insert(a,c);
                c=getchar();
                break;
            case '=':
//脱括号
                Pop(a);
                c=getchar();
                break;
            case'>':
                char f=Pop(a);
                int g=Pop2(b);
                int h=Pop2(b);
                Insert2(b,Operate(h,f,g));
                break;

            }

        }

    }
    cout<<"结果为"<<endl;
    cout<<GetPop2(b)<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_51222650/article/details/117048535