数据结构-算术表达式-算符优先法
来源:互联网 发布:网络弊大于利尖锐问题 编辑:程序博客网 时间:2024/04/30 03:49
代码还添加了乘方的优先级,自行参考
一开始我写的只能输入个位数,后来想了好久才解决,主要是在判断是否为运算符后,若不是运算符,别急着入栈,用一个标记数组记着,若下一个字符还不是运算符,则利用strcat函数链接之前标记数组和这一个字符,直到下一个字符是运算符为止,才入栈。
至于负数的运算,则要判断是否连续两个都为运算符,且前一个运算符为‘(’后一个运算符为‘-’,若是就加个0入栈即可。
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#define M 10#define add 10/*字符栈*/typedef struct{ char *base; int stacksize; int top;} sqstack;int init(sqstack &s){ s.base = (char *)malloc(M * sizeof(char)); if (!s.base) { exit(-1); } s.top = 0; s.stacksize = M; return 1;}int push(sqstack &s, char e){ char *newbase; if (s.top == s.stacksize) { newbase = (char *)realloc(s.base, (s.stacksize + add) * sizeof(char)); if (!newbase) { exit(-1); } s.base = newbase; s.stacksize += add; } s.base[s.top++] = e; return 1;}int pop(sqstack &s, char &e){ if (!s.top) { exit(-1); } e = s.base[--s.top]; return 1;}int Gettop(sqstack s, char &e){ if (!s.top) { exit(-1); } e = s.base[s.top - 1]; return 1;}/*操作数栈*/typedef struct{ float *base; int top; int stacksize;} datastack;int init_data(datastack &s){ s.base = (float *)malloc(M * sizeof(float)); if (!s.base) { exit(-1); } s.top = 0; s.stacksize = M; return 1;}int push_data(datastack &s, float e){ float *newbase; if (s.top == s.stacksize) { newbase = (float *)realloc(s.base, (s.stacksize + add) * sizeof(float)); if (!newbase) { exit(-1); } s.base = newbase; s.stacksize += add; } s.base[s.top++] = e; return 1;}int pop_data(datastack &s, float &e){ if (!s.top) { exit(-1); } e = s.base[--s.top]; return 1;}int gettop_data(datastack s, float &e){ if (!s.top) { exit(-1); } e = s.base[s.top - 1]; return 1;}/*判断算符优先关系*/char judge(char a, char b){ switch (a) { case '+': if (b == '+' || b == '-' || b == ')' || b == '#') { return '>'; } else { return '<'; } case '-': if (b == '+' || b == '-' || b == ')' || b == '#') { return '>'; } else { return '<'; } case '*': if (b == '(' || b == '^') { return '<'; } else { return '>'; } case '/': if (b == '(' || b == '^') { return '<'; } else { return '>'; } case '#': if (b == '#') { return '='; } else if (b == ')') { return ' '; /*返回空值,为后面判断与'=''>''<'区分*/ } else { return '<'; } case '(': if (b == ')') { return '='; } else if (b == '#') { return ' '; } else { return '<'; } case ')': if (b == '(') { return ' '; } else { return '>'; } case '^': if (b == '(') { return '<'; } else { return '>'; } default: return ' '; }}/*计算操作*/float action(float a, char k, float b){ switch (k) { case '+': return a + b; case '-': return a - b; case '*': return a * b; case '/': return a / b; case '^': return pow(a, b); default : return 0.0; }}/*判断运算符or操作数*/int isysf(char c){ if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')' || c == '#' || c == '^') { return 1; } return 0;}/*正片*/float hehe(char *input){ sqstack optr; datastack opnd; float a, b, data, ku = 0; int i = 0; float ans; int flag = 0; /*用作判断是否为负数*/ char e, x, y; char tempdata[20], ap[2] = {'#', '\0'}; char *c; init(optr); init_data(opnd); push(optr, '#'); c = strcat(input, ap); strcpy(tempdata, "\0"); Gettop(optr, e); while (c[i] != '#' || e != '#') { if (!isysf(c[i])) { ap[0] = c[i]; strcat(tempdata, ap); i++; if (isysf(c[i])) { data = atof(tempdata); push_data(opnd, data); strcpy(tempdata, "\0"); } flag = 0; } else { if (flag) /*若连续两个都是运算符*/ { Gettop(optr, y); if (y == '(' && c[i] == '-') /*判断输入是否为负数*/ { push_data(opnd, ku); /*0入操作数栈*/ push(optr, c[i]); i++; } else /*连续两个都是运算符却不是负数*/ { switch (judge(e, c[i])) { case '<': push(optr, c[i]); i++; break; case '=': pop(optr, x); i++; break; case '>': pop(optr, e); pop_data(opnd, a); pop_data(opnd, b); push_data(opnd, action(b, e, a)); break; } } } else { switch (judge(e, c[i])) { case '<': push(optr, c[i]); i++; break; case '=': pop(optr, x); i++; break; case '>': pop(optr, e); pop_data(opnd, a); pop_data(opnd, b); push_data(opnd, action(b, e, a)); break; } } flag = 1; } Gettop(optr, e); } gettop_data(opnd, ans); return ans;}int main(){ float a; char c[1111]; printf("****************************************************************\n"); printf("\n加法:+ 减法:- 乘法:* 除法:/ 乘方:^ \n"); printf("\n数值可为任意实数,输入负数必须用括号()括起来,结果保留2位小数\n\n"); printf("****************************************************************\n\n"); while (1) { printf("输入表达式:\n"); gets(c); a = hehe(c); printf("表达式的值为:%.2f\n", a); } return 0;}
0 0
- 数据结构-算术表达式-算符优先法
- 算术表达式求值的算符优先算法
- 7.栈的应用-四则运算算术表达式求解(算符优先法)
- 算术表达式求值:“算符优先级法”、“后缀表达式法”
- 数据结构课程设计 算术表达式求值
- 数据结构---栈:一般算术表达式
- 算术表达式的语法和语义分析(算符优先分析方法生成三元式的中间代码)
- 【数据结构】利用栈来求算术表达式的值
- 数据结构中利用栈计算算术表达式
- 11 算术运算符与算术表达式
- C++算术运算符与算术表达式
- lesson11 算术运算符与算术表达式
- 算术运算符和表达式
- 数据结构:算符优先法(栈的应用)
- 正则表达式法计算字符串算术表达式
- 算术表达式
- 算术表达式
- 算术表达式
- 前端开发过程中需要注意的细节
- ios深度解析之Swift(分支语句)
- ColorFilter与ColorMatrix
- 堆内存和栈内存详解
- RID、DR、BDR以及广播多路访问、非广播多路访问实验
- 数据结构-算术表达式-算符优先法
- 为了让你的网页能在更多的服务器上正常地显示,还是加上“SET NAMES UTF8”吧
- node.js学习二(Express4.x)
- iOS--自定义提示框
- coordinatorlayout 显示错乱问题
- 几个性能测试工具
- 所用的软件是visualc++6.0绿色版,点击运行后出现[local]1[/local]
- C++多线程编程入门
- 使用nginx简单实现反向代理和负载均衡