栈的应用

来源:互联网 发布:去向分布图用什么软件 编辑:程序博客网 时间:2024/06/18 15:04

思路:

先将字符串进行化简——多位整数,单位整数,浮点数和字符分开

构造一个结构体类型的数组s,存储化简后的中缀表达式

构造一个结构体类型的栈,进行转换

构造一个结构体类型的数组l,存储后缀表达式

构造一个结构体类型的栈,计算后缀表达式

一.存储

gets比较方便输入,扫描字符串,将字符串存入到s中;

二.中缀表达式转后缀表达式

扫描中缀表达式1.遇到操作数:直接输出(添加到后缀表达式中)2.栈为空时,遇到运算符,直接入栈3.遇到左括号:将其入栈4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈

三.后缀表达式输出

<pre name="code" class="cpp">设置一个栈,开始时,栈为空;然后从左到右扫描l中的后缀表达式,若遇操作数,则进栈;若遇运算符,则从栈中退出两个元素,运算后的结果再进栈,直到后缀表达式扫描完毕。此时,栈中仅有一个元素,即为运算的结果。

/*********************************************************1.支持多位正整数,正浮点数2.支持加减乘除3.支持空格4.支持回车空输入5.支持多次输入6.除以0检错7.支持表达式合法检测:首末不能有字符(可以有'('或')'):括号必须成对:字符不能连续出现:左括号的左边不能为数字,右边不能为符号:右括号的左边不能为符号,右边不能为数字//尚未解决:负数运算*********************************************************/

#include <cstdio>#include <cstdlib>#include <iostream>#include <stack>#include <queue>#include <algorithm>#include <cstring>#include <cmath>#include <vector>#include <bitset>#include <list>#include <sstream>#include <set>#include <functional>using namespace std;#define Max_ 0X3f3f3f3fint i = 0;int j = 0;int k = 0;int m = 0;int zuo;int you;int begin;int end = Max_;int illegal;char in[Max_] = {0};struct sta{    int order;    int flag = 0;//1为int,2为float,3为char    int data1;    double data2;    char data3;}s[1000],out,l[1000];stack <sta> hello;stack <sta> world;//判断是否为数字int number(char c){    if ((c>='0'&&c<='9')||(c=='.'))        return 1;    else        return 0;}//判断是否为合法字符int mark(char c){    if (c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='#')        return 1;    else        return 0;}//判断结构体是否为存数的结构体int shu(struct sta c){    if((c.flag == 1)||(c.flag == 2))        return 1;    else        return 0;}//判断结构体是否为存符号的结构体int fu(struct sta c){    if(c.flag == 3)        return 1;    else        return 0;}//删除空格void delete_space(){    char c;    for (int i = 0; i < strlen(in); i += 1)    {        if (in[i] == ' ')        {            int j;            for (j = i; j < strlen(in)-1; j += 1)            {                in[j] = in[j+1];            }            in[j] = '\0';        }    }}void print(struct sta r){    if(r.flag == 1){        printf("%d",r.data1);    }    else if(r.flag == 2){        printf("%lf",r.data2);    }    else if(r.flag == 3){        printf("%c",r.data3);    }}void test(){    for(int j = 0;j < k;j++)    {        print(s[i]);    }    printf("\n");}//多位数或浮点数的处理void deal(int sta,int en)//youwenti{    //printf("%d%d\n",sta,en);//start end ok    int fla = 0,point;    for(int i = sta;i<=en; i++)//区分浮点数还是多位数,ok    {        if(in[i] == '.'){            fla =  1;            point  = i;            break;        }    }    if(fla)//浮点数    {        //printf("Fudianshu\n");        double sum = 0;        for(int j = sta;j<point;j++){            sum += (in[j]-'0')*(float)pow(10,point-j-1);        }        for(int j = point+1;j<=en;j++){            sum += (in[j]-'0')*(float)pow(10,point-j);        }        s[k].flag = 2;        s[k].data2 = sum;//        printf("%d ",k);//        printf("%lf\n",s[k].data2);        s[k].order = k;        k++;    }    else//多位整数    {        //printf("Duoweizhengshu");        int sum = 0;        int a = en-sta;        for(int j = sta;j <= en;j++)        {            sum += (in[j]-'0')*(float)(pow(10,a));            //printf("%d\n",sum);            a--;        }        s[k].flag = 1;        s[k].data1 = sum;//        printf("%d %d\n",k,s[k].data1);        s[k].order = k;        k++;    }    return ;}void store()//存储到s{    memset(s,0,sizeof(s[0]));    begin = 0;    for (i = 0; i < strlen(in); i += 1)    {        if(mark(in[i])){//字符            begin = i+1;            s[k].flag = 3;            s[k].data3 = in[i];            //printf("%c\n",s[k].data3);            k++;        }        else if(number(in[i])){//数字            for(int j = i+1;j<=strlen(in);j++){                if(mark(in[j])||(j==strlen(in))){                    i = j-1;//下位调到字符继续搜索                    end = j-1;                    break;                }            }            if(end-begin){                deal(begin,end);            }            else{//单位整数ok                s[k].flag = 1;                s[k].data1 = (in[i]-'0');                //printf("%d %d\n",k,s[k].data1);                k++;            }        }    }    return ;}void judge(){    for(int j = 0; j < k; j++)//判断括号    {        if(fu(s[j])){            if(s[j].data3=='(')            {                zuo++;//右边不能为字符                if((j+1<k)&&((s[j+1].data3=='+')||(s[j+1].data3=='-')||(s[j+1].data3=='*')||(s[j+1].data3=='/')))                {                    illegal = 2;                    return ;                }                if((j-1>=0)&&(shu(s[j-1])))//左边不能为数字                {                    //printf("Ilegal expression,please input again\n");                    illegal = 2;                    return ;                }                if(((j+1<k)&&(s[j+1].data3==')'))||(j==k-1))//空格中不能为空,不能放鸽子;不能为尾                {                    illegal = 2;                    return ;                }            }            else if(s[j].data3==')')            {                you++;//左边不能为字符                if((j-1>=0)&&((s[j-1].data3=='+')||(s[j-1].data3=='-')||(s[j-1].data3=='*')||(s[j-1].data3=='/')))                {                    //printf("Ilegal expression,please input again\n");                    illegal = 2;                    return ;                }                if(((j+1<k)&&(shu(s[j+1])))||(j==0))//右边不能为数字;不能为首                {                    //printf("Ilegal expression,please input again\n");                    illegal = 2;                    return ;                }            }            else if((s[j].data3=='+')||(s[j].data3=='-')||(s[j].data3=='*')||(s[j].data3=='/'))            {                if((j==0)||(j==k-1))//首尾不能为字符                {                    //printf("Ilegal expression,please input again\n");                    illegal = 2;                    return ;                }                else if((s[j-1].data3=='+')||(s[j-1].data3=='-')||(s[j-1].data3=='*')||(s[j-1].data3=='/'))                {                    //printf("Ilegal expression,please input again\n");                    illegal = 2;                    return ;                }                else if((s[j+1].data3=='+')||(s[j+1].data3=='-')||(s[j+1].data3=='*')||(s[j+1].data3=='/'))                {                    //printf("Ilegal expression,please input again\n");                    illegal = 2;                    return ;                }            }        }    }    if(zuo!=you){        printf("Ilegal expression,please input again\n");        illegal = 2;        return ;    }}void in_data()//ok{    memset(in,0,sizeof(in[0]));    illegal = 0;    k = 0;    zuo = 0;    you = 0;    printf("Please input:");    gets(in);//输入    delete_space();    if(strlen(in)==0){//不断回车,跳过        illegal =  3;        return ;    }    if(in[0] == '#'){//结束符        illegal = 1;        return ;    }    for(i = 0;i < strlen(in);i++)    {        if(!mark(in[i]) && !number(in[i])){//            printf("Wrong inputs!\n");            illegal =  3;            return ;        }    }    store();//存储    judge();//表达式的判断    //printf("%d",k);    return ;}int nless(char a,char b)//a>=b{    if((a=='(')&&(b!='(')){        return 0;    }    else if(a=='+'||a=='-'){        if(b=='*'||b=='/'){            return 0;        }    }    else return 1;}void middle_later()//扫描s,l赋值有问题{    memset(l,0,sizeof(l[0]));    while(!hello.empty()){        hello.pop();    }    m = 0;    printf("Postfix Expression:");    for(int j = 0;j < k; j++)    {        //栈为空时,遇到运算符直接入栈        if(hello.empty()&&fu(s[j])){            hello.push(s[j]);        }        //遇到操作数,直接输出        else if(shu(s[j])){            print(s[j]);            l[m] = s[j];            m++;            printf(" ");        }        //遇到左括号,入栈        else if(fu(s[j])&&s[j].data3 == '('){            hello.push(s[j]);        }        //遇到右括号,执行出栈操作,直至弹出的栈为左括号,左括号不输出        else if(fu(s[j])&&s[j].data3 == ')'){            while(!hello.empty())            {                out = hello.top();                if(out.data3 != '('){                   print(out);                   l[m] = out;                   m++;                   printf(" ");                   hello.pop();                }                else{                    hello.pop();                    break;                }            }        }        //遇到加减乘除,弹出所有优先级不小于该运算符的栈顶元素,然后将该运算符入栈        else if(fu(s[j]))        {            while(!hello.empty())            {                out = hello.top();                if(nless(out.data3,s[j].data3))                {                    print(out);                    l[m] = out;                    m++;                    printf(" ");                    hello.pop();                }                else                    break;            }            hello.push(s[j]);        }    }    while(!hello.empty())    {        out = hello.top();        print(out);        l[m] = out;        m++;        printf(" ");        hello.pop();    }    printf("\n");//    for(int j = 0; j < k; j++)//    {//        print(l[j]);//    }//    printf("\n");}double data(struct sta c){    if(c.flag==1)        return c.data1;    else if(c.flag==2)        return c.data2;}void with(struct sta b,char c,struct sta a){    struct sta d;    double ans = 0;    switch(c)    {        case '+':ans = data(b)+data(a);break;        case '-':ans = data(b)-data(a);break;        case '*':ans = data(b)*data(a);break;        case '/':        {            if(data(a)==0)            {                printf("No ends,sorry\n");                illegal =  2;                return ;            }            ans = data(b)/data(a);            break;        }    }    d.flag = 2;    d.data2 = ans;    world.push(d);    return ;}void later_out(){    struct sta a,b;    while(!world.empty()){            world.pop();    }    for(int j = 0; j < m; j++)    {        //print(l[j]);//ok        if(shu(l[j])){            world.push(l[j]);        }        else if(fu(l[j]))        {            a = world.top();            world.pop();            b = world.top();            world.pop();            with(b,l[j].data3,a);            if(illegal==2)                return ;        }    }    printf("Answer:");    print(world.top());    printf("\n\n");    return;}int main(int argc, char const* argv[]){    while (1)    {        //输入及存储        in_data();        if(illegal == 1)    break;        if(illegal == 2){printf("Ilegal expression,please check again\n");continue;}        if(illegal == 3)    continue;        //中缀转后缀        middle_later();        //后缀计算输出        later_out();//youcuowu        if(illegal == 2)    continue;    }    return 0;}







1 0
原创粉丝点击