其他分享
首页 > 其他分享> > 数据结构(严蔚敏)3.2栈的应用举例

数据结构(严蔚敏)3.2栈的应用举例

作者:互联网

学习记录,仅供参考,希望可以指出错误

头文件就上已经上传过的顺序栈的随笔的修改。

#include"stack_shunxu.h"
//算法3.1        3.2.1 数制转换,对于输入的任意非负十进制整数,打印输出其八进制形式
void conversion(){
    int num;
    sqstack s;initstack(s);
    printf("请输入:");
    scanf("%d",&num);
    while(num){
        push(s,(elemtype)num%8);
        num=num/8;
    }
    while(!stackempty(s)){
        elemtype e;
        pop(s,e);
        printf("%d",(int)e);
    }
}

//3.2.2 括号匹配的检验 (不推荐)
void match(){
    sqstack s;initstack(s);
    scanf_stack2(s);
    printf("开始输入:\n");display(s,' ');
    if(stacklength(s)%2!=0||stacklength(s)==0){//如果%2不为0,则直接退出
        printf("\n括号格式错误1\n");
        exit(0);
    }
    sqstack t;initstack(t);
    while(!stackempty(s)){
        elemtype e1=NULL,e2=NULL;
        gettop(t,e1);
        gettop(s,e2);
        if((e1=='}'&&e2=='{')||(e1==']'&&e2=='[')){
            pop(t,e1);
            pop(s,e2);
        }
        else{
            pop(s,e2);
            push(t,e2);
        }
    }
    if(stackempty(s)&&stackempty(t)){
        printf("\n括号配对\n");
    }else{
        printf("\n括号格式错误2\n");
    }
    destorystack(s);
    destorystack(t);
}

//3.2.3 行编辑器 #退格符 @退行符 `全文结束符
void lineedit(){
    sqstack s;initstack(s);
    elemtype e=NULL;
    printf("开始输入:\n");
    while(e!='`'){
        if(e!='#'&&e!='@'){
        scanf("%c",&e);
        push(s,e);    
        }
        else if(e=='#'){
            pop(s,e);
        }
        else if(e=='@'){
            while(e!='\n'&&!stackempty(s)){
                pop(s,e);
            }
        }
    }
    pop(s,e);
    display(s,' ');
}
//算法3.2    (3.2.3教材实现)
void LineEdit(){
    sqstack s;initstack(s);
    char ch=getchar();
    while(ch!='`'){
        while(ch!='`'&&ch!='\n'){
            elemtype c;
            switch(ch){
            case '#':pop(s,c);break;
            case '@':clearstack(s);break;
            default:push(s,ch);
            }
            ch=getchar();
        }
        display(s,' ');
        clearstack(s);
        if(ch!='`')ch=getchar();
        else{
            printf("输入了退出\n");
        }
    }
    destorystack(s);
}

//3.2.4 迷宫求解
int method(int a,int b,int c,int d,char s[10][10]){//本方法是,走向的优先度为右,上,下,左,从坐标ab开始,
    //依次按照优先度查找方向,走过的位置都标记为%,存入数组,(如果是墙壁*,就找下一个方向,如果四周都是*或者%就退栈,把当前坐标在数组里标记为*,然后返回上一次的坐标,
    sqstack t;
    initstack(t);
    struct wz{
        int i;
        int j;
    }q,p;
    char e;
        q.i=a;q.j=b;//起始
        p.i=c;p.j=d;//终点
        s[q.i][q.j]='%';//当前
        printf("\n");
        while(q.i!=p.i||q.j!=p.j){                                             //如果起点坐标和终点坐标不一样循环
            printf("当前:%d,%d        终点:%d,%d\n",q.i,q.j,p.i,p.j);
            if(s[q.i][q.j+1]!='*'&&s[q.i][q.j+1]!='%') //如果右边不为墙壁向右边移动
            { s[q.i][q.j]='%';q.j=q.j+1;            push(t,'d');}
            else if(s[q.i-1][q.j]!='*'&&s[q.i-1][q.j]!='%') //如果上边不为墙壁向上边移动
            { s[q.i][q.j]='%';q.i=q.i-1;            push(t,'w');}            
            else if(s[q.i+1][q.j]!='*'&&s[q.i+1][q.j]!='%') //如果下边不为墙壁向下边移动
            { s[q.i][q.j]='%';q.i=q.i+1;            push(t,'s');}
            else if(s[q.i][q.j-1]!='*'&&s[q.i][q.j-1]!='%') //如果左边不为墙壁向左边移动
            { s[q.i][q.j]='%';q.j=q.j-1;            push(t,'a');}
            else 
            {//如果四周都是* 或者% 就输出栈顶元素,并且把这个地方赋值* ,然后返回上一个地方
                s[q.i][q.j]='*';
                pop(t,e);
                if(e=='a'){ q.j=q.j+1;}
                else if(e=='s'){ q.i=q.i-1;}
                else if(e=='w'){ q.i=q.i+1;}
                else if(e=='d'){ q.j=q.j-1;;}
            }
        }
        printf("栈的元素个数为%d\n",stacklength(t));
        printf("\n\n参考步骤:\n\n");
        display(t,'\n');
        return 0;
}
void maze(){
    char m[10][10];
    for(int i=0;i<9;i++)
        for(int j=0;j<9;j++)
            m[i][j]=' ';
    for(int i=0;i<10;i++)
        {
            m[0][i]='*';//第一行
            m[i][0]='*';//第一列
            m[9][i]='*';//第十行
            m[i][9]='*';//第十列
            }
    m[8][1]=m[6][2]=m[7][2]=m[1][3]=m[2][3]=m[4][3]=m[7][3]=m[4][4]=m[5][4]=m[7][4]=m[3][5]=m[3][6]=m[6][6]=m[7][6]=m[1][7]=m[2][7]=m[4][2]='*';

    for(int i=0;i<10;i++){
        printf("\n");
        for(int j=0;j<10;j++)
            printf(" %c",m[i][j]);
    }
    method(1,1,8,8,m);
}

//3.2.5 表达式求值
int in(char c,char op[]){
    int num=sizeof(op);
    for(int i=0;i<num;i++)
        if(op[i]==c) return OK;
    return ERROR;
}
char precede(char a,char b){//判断优先级
    char or;
    switch(a){
    case '+':
    case '-':
        if(b=='+'||b=='-'||b==')')
            or='>';
        else or='<';
        break;


    case '*':
    case '/':
        if(b=='(')
            or='<';
        or='>';
        break;


    case '(':
        if(b==')')
            or='=';
        else if(b=='#')
            or=NULL;
        else
            or='<';
        break;

    case ')':
        if(b=='(')
            or=NULL;
        else or='>';
        break;

    case'#':
        if(b==')')
            or=NULL;
        else if(b=='#')
            or='=';
        else or='<';
        break;
    }
    return or;
}
char operate(char *a,char b,char *c){
/*elemtype给的是char,那么我如果一次性输入一个表达式,例如111*111#,(#是结束符和开始符,开始符已经自动输入了),他存的是:’1’,’1’,’1’,’*’,’1’,’1’,’1’,’#’一共七个字符。那也就是说,如果实现表达式求值那么只能实现个位数求值。
因为elemtype给的是char,当为char,栈内就只能存个位数,当为int,栈就不能存符号。
如果我改成char*,那么输入111*111#的话就要额外设置一个函数来判断一个字符的下一个是符号还是数字,然后分清后,数字和符号再分别存入栈,而且还要修改我已经写好的代码。
还是说再写个elemtype为int的栈。
*/
//这里理解就好
}

//算法3.4
elemtype evaluateexpression(){
    //OPTR为运算符栈,OPND为运算数栈
    //OP为运算符集合
    //    TR---------符号        ND----------数字
    sqstack OPTR,OPND;
    initstack(OPTR);initstack(OPND);
    push(OPTR,'#');
    char c=getchar();
    elemtype e;gettop(OPTR,e);
    while(c!='#'||e!='#'){
        char OP[]={'+','-','*','/','(',')','#'};
        if(!in(c,OP)){//不是运算符进栈
            push(OPND,c);
            c=getchar();
        }
        else{
            elemtype gett;gettop(OPTR,gett);
            switch(precede(gett,c)){
            case'<':
                push(OPTR,c);c=getchar();
                break;
            case'=':
                elemtype x;pop(OPTR,x);c=getchar();
                break;
            case'>':
                elemtype theta,a,b;
                pop(OPTR,theta);
                pop(OPND,b);
                pop(OPND,a);
                push(OPND,operate(a,theta,b));
                break;
            }
        }
    }
    elemtype end;gettop(OPND,end);
    return end;

}
void main(){
    //lineedit();
    //LineEdit();
    //match();
    //maze();
}

 

标签:ch,int,pop,else,严蔚敏,3.2,&&,printf,数据结构
来源: https://www.cnblogs.com/liuyueshu/p/14814921.html