逆波兰计算器的实现

来源:互联网 发布:mac键盘灯怎么开 编辑:程序博客网 时间:2024/04/28 18:23
话不多说先上代码供大佬们检查
#include"stdio.h"#include"stdlib.h"#include"memory.h"#define MAXSIZE 100typedef struct MStack{char data[MAXSIZE];int top;};MStack *InitStack(){MStack *ms;ms = (MStack*)malloc(sizeof(MStack));memset(ms->data, 0, MAXSIZE);ms->top = -1;return ms;}void PushStack(MStack *ms, char e){if (ms->top == MAXSIZE - 1){printf("栈满溢出");return;}ms->data[++ms->top] = e;}void PopStack(MStack *ms, char *e){if (ms->top == -1){printf("栈空!");return;}*e = ms->data[ms->top--];}int PriCal(char c){if (c == '-' || c == '+')return 1;if (c == '*' || c == '/')return 2;if (c == '(' || c == ')')return 3;return false;}int main(){MStack *ms;MStack *msn;msn = InitStack();ms = InitStack();char above = 9;//保存上一次的输入值,检测输入算式是否合法char c;char num;int e;c = getchar();//以下是将普通中缀表达式改为后缀表达式while (1){e = 0;//if (c == '\n')//{//if (!(above != ')' || (above <= '9' && above >= '0')))//{//printf("输入算式有错,请检查后重新运行此程序!");//return -1;//}//while (ms->top != -1)//{//PopStack(ms, &c);//PushStack(msn, c);//}//break;//}if (c <= '9' && c >= '0'){if (ms->top != -1){if (above != '+' && above != '-' && above != '*' && above != '/' && above != '('){printf("输入算式有错,请检查后重新运行此程序!");return -1;}}while (c <= '9' && c >= '0'){e = e * 10 + c - '0';above = c;c = getchar();}PushStack(msn, (char)(e + '0'));}if (c == '+' || c == '-' || c == '*' || c == '/'){if (!(above != ')' || (above <= '9' && above >= '0'))){printf("输入算式有错,请检查后重新运行此程序!");return -1;}if (ms->top == -1)PushStack(ms, c);else if (PriCal(ms->data[ms->top]) >= PriCal(c)){while (PriCal(ms->data[ms->top]) >= PriCal(c)){if (ms->data[ms->top] == '(')break;num = c;PopStack(ms, &num);PushStack(msn, num);}PushStack(ms, c);}else PushStack(ms, c);}if (c == '(' || c == ')'){if (c == '('){if (above != '+' &&above != '-' &&above != '*' &&above != '/'&&ms->top != -1){printf("输入算式有错,请检查后重新运行此程序!");return -1;}PushStack(ms, c);}if (c == ')'){if (above < '0' || above > '9'){printf("输入算式有错,请检查后重新运行此程序!");return -1;}while (c != '('){PopStack(ms, &c);if (c != '(')PushStack(msn, c);}}}above = c;if (c == '\n')break;else c = getchar();}while (msn->top != -1){PopStack(msn, &c);PushStack(ms, c);}/*PushStack(ms, '+');PushStack(ms, '/');PushStack(ms, '2');PushStack(ms, '8');PushStack(ms, '+');PushStack(ms, '*');PushStack(ms, '3');PushStack(ms, '-');PushStack(ms, '1');PushStack(ms, '3');PushStack(ms, '9');*///以下是计算部分while (ms->top != -1){if (ms->data[ms->top] <= '0' + 255 && ms->data[ms->top] >= '0')//原本数据范围是'0'-'9',如果要计算10以外则需要加大为'0'-'0'+255{PopStack(ms, &c);PushStack(msn, c);}if (ms->data[ms->top] == '+'){PopStack(ms, &c);PopStack(msn, &c);PopStack(msn, &num);num = (int)(num - '0') + (int)(c - '0') + '0';PushStack(msn, num);}if (ms->data[ms->top] == '-'){PopStack(ms, &c);PopStack(msn, &c);PopStack(msn, &num);num = (int)(num - '0') - (int)(c - '0') + '0';PushStack(msn, num);}if (ms->data[ms->top] == '/'){PopStack(ms, &c);PopStack(msn, &c);PopStack(msn, &num);num = (char)(int)(num - '0') / (int)(c - '0') + '0';PushStack(msn, num);}if (ms->data[ms->top] == '*'){PopStack(ms, &c);PopStack(msn, &c);PopStack(msn, &num);num = (int)(c - '0')*(int)(num - '0') + '0';PushStack(msn, num);}}printf("%d", msn->data[msn->top] - '0');return 0;}

以上就是我的全部代码


逆波兰算法无非是中缀表达式转换为后缀表达式,然后通过后缀表达式求值。刚开始尝试的时候想法比较大一直想一次性实现,耽误我一天时间,后面分两个模块就实现挺快的  == 。

栈的基本操作没啥可以说的,那我们就不说了,先说说实现后缀表达式的计算这块,

while (ms->top != -1){if (ms->data[ms->top] <= '9' && ms->data[ms->top] >= '0')//原本数据范围是'0'-'9',如果要计算10以外则需要加大为'0'-'0'+255{PopStack(ms, &c);PushStack(msn, c);}if (ms->data[ms->top] == '+'){PopStack(ms, &c);PopStack(msn, &c);PopStack(msn, &num);num = (int)(num - '0') + (int)(c - '0') + '0';PushStack(msn, num);}if (ms->data[ms->top] == '-'){PopStack(ms, &c);PopStack(msn, &c);PopStack(msn, &num);num = (int)(num - '0') - (int)(c - '0') + '0';PushStack(msn, num);}if (ms->data[ms->top] == '/'){PopStack(ms, &c);PopStack(msn, &c);PopStack(msn, &num);num = (char)(int)(num - '0') / (int)(c - '0') + '0';PushStack(msn, num);}if (ms->data[ms->top] == '*'){PopStack(ms, &c);PopStack(msn, &c);PopStack(msn, &num);num = (int)(c - '0')*(int)(num - '0') + '0';PushStack(msn, num);}}

此时数据只接受'0'-'9'的数字的加减法,一次次输入太麻烦我就一次性给输入为9 3 1 - 3 * + 8 2 / +;9是栈顶元素,这相当于计算9+(3-1)*3+8/2,结果算出来没有啥错误,这块是比较简单的。

MStack *ms;MStack *msn;msn = InitStack();ms = InitStack();char above = 9;//保存上一次的输入值,检测输入算式是否合法char c;char num;int e;c = getchar();//以下是将普通中缀表达式改为后缀表达式    while (1)    {        if (c == '\n')        {            while (ms->top != -1)            {                PopStack(ms, &c);                PushStack(msn, c);            }            break;        }        if (c <= '9' && c >= '0')            PushStack(msn, c);        if (c == '+' || c == '-' || c == '*' || c == '/')        {            if (ms->top == -1)                PushStack(ms, c);            else if (PriCal(ms->data[ms->top]) >= PriCal(c))            {                while (PriCal(ms->data[ms->top]) >= PriCal(c))                {                    if (ms->data[ms->top] == '(')break;                    num = c;                    PopStack(ms, &num);                    PushStack(msn, num);                }                PushStack(ms, c);            }            else PushStack(ms, c);        }        if (c == '(' || c == ')')        {            if (c == '(')PushStack(ms, c);            if (c == ')')            {                while (c != '(')                {                    PopStack(ms, &c);                    if(c != '(')                        PushStack(msn, c);                }            }        }        c = getchar();    }


我们现在实现了中后缀表达式转化,这儿关注的只是加减乘除的表达式转化,没怎么注意数字的,但是这样数字也差不多(如果只是单个字符的话)

我们给程序加个错误判断,above存储上一个输入的字符的值,如果我们这次输入为数字上次就必须是左括号或者操作符其它判断类似。但是如果栈内数据为空还需要单独判断。

同时再加个小小的操作让数据能处理非单个字符的运算

    MStack *ms;    MStack *msn;    msn = InitStack();    ms = InitStack();    char above = 9;//保存上一次的输入值,检测输入算式是否合法    char c;    char num;    int e;    c = getchar();    //以下是将普通中缀表达式改为后缀表达式    while (1)    {        e = 0;        //if (c == '\n')        //{            //if (!(above != ')' || (above <= '9' && above >= '0')))            //{            //    printf("输入算式有错,请检查后重新运行此程序!");            //    return -1;            //}            //while (ms->top != -1)            //{            //    PopStack(ms, &c);            //    PushStack(msn, c);            //}            //break;        //}        if (c <= '9' && c >= '0')        {            if (ms->top != -1)            {                if (above != '+' && above != '-' && above != '*' && above != '/' && above != '(')                {                    printf("输入算式有错,请检查后重新运行此程序!");                    return -1;                }            }            while (c <= '9' && c >= '0')            {                e = e * 10 + c - '0';                above = c;                c = getchar();            }            PushStack(msn, (char)(e + '0'));        }        if (c == '+' || c == '-' || c == '*' || c == '/')        {            if (!(above != ')' || (above <= '9' && above >= '0')))            {                printf("输入算式有错,请检查后重新运行此程序!");                return -1;            }            if (ms->top == -1)                PushStack(ms, c);            else if (PriCal(ms->data[ms->top]) >= PriCal(c))            {                while (PriCal(ms->data[ms->top]) >= PriCal(c))                {                    if (ms->data[ms->top] == '(')break;                    num = c;                    PopStack(ms, &num);                    PushStack(msn, num);                }                PushStack(ms, c);            }            else PushStack(ms, c);        }        if (c == '(' || c == ')')        {            if (c == '(')            {                if (above != '+' &&above != '-' &&above != '*' &&above != '/'&&ms->top != -1)                {                    printf("输入算式有错,请检查后重新运行此程序!");                    return -1;                }                PushStack(ms, c);            }            if (c == ')')            {                if (above < '0' || above > '9')                {                    printf("输入算式有错,请检查后重新运行此程序!");                    return -1;                }                while (c != '(')                {                    PopStack(ms, &c);                    if (c != '(')                        PushStack(msn, c);                }            }        }        above = c;        if (c == '\n')break;        else c = getchar();    }

注意在最后的c=getchar()前一定要加个c是否为换行符的判断,因为其它读取字符的操作可能它后面需要读取字符的时候,我们的输入已经没有字符了,又得让我们继续输入导致算式出错,同时记得把后缀表达式计算的数据范围改成

if (ms->data[ms->top] <= '0' + 255 && ms->data[ms->top] >= '0')//原本数据范围是'0'-'9',如果要计算10以外则需要加大为'0'-'0'+255

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手干活磨起泡了怎么办 手上磨了个水泡怎么办 手指磨出水泡了怎么办 手上磨了个泡怎么办 脚上的水泡破了怎么办 脚上水泡破了怎么办 烫伤之后破皮了怎么办 皮肤被烫伤破皮怎么办 烫伤起泡皮掉了怎么办 被烫伤起大水泡怎么办 被烫伤起小水泡怎么办 脚走路磨起泡了怎么办 脚趾头磨了个泡怎么办 脚趾头起了大泡怎么办 脚上有脚气起水泡很痒怎么办 脚底有水泡很痒怎么办 脚底磨得起泡了怎么办 脚底有水泡很疼怎么办 脚底硬皮走路疼怎么办 上火鼻子上长脓包怎么办 鼻子上总是长脓包怎么办 孕妇脚上长水泡很痒怎么办 脚气有水泡很痒怎么办 脚又痒又脱皮怎么办 手指出水泡很痒怎么办 鼻子里上火长泡怎么办 鼻子又干又痒怎么办 眼皮长了小水泡怎么办 眼皮上长了个泡怎么办 眼皮上长了粉刺怎么办 上眼皮又肿又疼怎么办 眼皮长了个痘怎么办 手指上小水泡痒怎么办 阴茎长了一个泡怎么办 干活累的腰疼怎么办 手长白色的小泡怎么办 全身长水泡很痒怎么办 自吸泵声音大怎么办 索尼镜头盖丢了怎么办 15-45镜头盖丢了怎么办 手机镜头盖丢了怎么办