专门用来对付运算式子的一个算法
例如我们做到一个计算器的时候我们会遇到1+9+6/8类似这种,那么我们就可以用把这个式子变成后缀表达式然后再来计算。
struct//设定运算符的优先级 { char ch;//运算符 int pri;//优先级 }lpri[] = { { '=', 0 }, { '(', 1 }, { '*', 5 }, { '/', 5 }, { '+', 3 }, { '-', 3 }, { ')', 6 } }, rpri[] = { { '=', 0 }, { '(', 6 }, { '*', 4 }, { '/', 4 }, { '+', 2 }, { '-', 2 }, { ')', 1 } }; int leftpri(char op)//左边运算符的优先级 { int i; for (i = 0; i<7; i++) if (lpri[i].ch == op)return lpri[i].pri; } int rightpri(char op)//右运算符的优先级 { int i; for (i = 0; i<7; i++) if (rpri[i].ch == op) return rpri[i].pri; } bool InOp(char ch)//判断ch是不是运算符 { if (ch == '(' || ch == ')' || ch == '+' || ch == '-' || ch == '*' || ch == '/') return true; else return false; } int Precede(char op1, char op2)//op1和op2运算符的优先级情况 { if (leftpri(op1) == rightpri(op2)) return 0; if (leftpri(op1)<rightpri(op2)) return -1; else return 1; } void trans(char *exp, char postexp[])//将一般的表达式转成后缀表达式 { struct //存放运算符 { char data[1000]; int top;//栈指针 }op; int i = 0; op.top = -1; op.top++; op.data[op.top] = '='; while (*exp != '\0')//exp表达式未扫描完时循环 { if (!InOp(*exp))//若是数字的时候 { while (*exp >= '0'&&*exp <= '9')//判断为数字 { if (*(exp - 2) == '(' && (*(exp - 1) == '+' || *(exp - 1) == '-' || *(exp - 1) == '*' || *(exp - 1) == '/'))//是是负数的符号而不是减号 { postexp[i++] = '&';//这个是为了处理负数的情况,如果是负数则会出现&和数字 例如&5 int a = i + 1; postexp[a++] = *exp; } postexp[i++] = *exp; exp++;//存放表达式 } postexp[i++] = '#';//用一个#号隔开 } else//如果是运算符的情况 { if ((*exp == '+' || *exp == '-' || *exp == '*' || *exp == '/') && *(exp - 1) == '(' && (*(exp + 1) >= '0'&&*(exp + 1) <= '9'))//除掉是负数的-号 { exp++; continue; } else { switch (Precede(op.data[op.top], *exp)) { case -1://栈顶运算符的优先级低 op.top++; op.data[op.top] = *exp; exp++; break; case 0://只有括号满足这种情况 op.top--; exp++; break; case 1://退栈并输入到postexp数组中 postexp[i++] = op.data[op.top]; op.top--; break; } } } } while (op.data[op.top] != '=')//此时已经扫描好了,退栈到'='结束 { postexp[i++] = op.data[op.top]; op.top--; } postexp[i] = '\0';//添加一个结束标志 } float compvalue(char *postexp)//通过后缀表达式开始计算值 { struct { float data[1000];//存放数字的数组 int top; }st; float d, a, b, c; st.top = -1; while (*postexp != '\0')//当postexp字符串为扫描完时 { switch (*postexp) { case '+'://判断是'+’的时候 a = st.data[st.top]; st.top--; b = st.data[st.top]; st.top--; c = a + b; st.top++; st.data[st.top] = c;//这就是计算两个数字相加的时候a,b退栈计算c然后进栈 break; case '-': a = st.data[st.top]; st.top--; b = st.data[st.top]; st.top--; c = b - a; st.top++; st.data[st.top] = c; break; case '*': a = st.data[st.top]; st.top--; b = st.data[st.top]; st.top--; c = b*a; st.top++; st.data[st.top] = c; break; case '/': a = st.data[st.top]; st.top--; b = st.data[st.top]; st.top--; if (a != 0) { c = b / a; st.top++; st.data[st.top] = c; } else { printf("error(分母为0)\n"); exit(0); } break; default: d = 0; int find = 0; while (*postexp >= '0'&&*postexp <= '9'&&*postexp != '&') { if (*(postexp - 1) == '&') { find = 1; } else { find = -1; } d = 10 * d + *postexp - '0'; postexp++; } if (find == 1) { st.top++; st.data[st.top] = -d; } else if (find == -1) { st.top++; st.data[st.top] = d; } break; } postexp++; } return(st.data[st.top]);//最后指针指的位置就是值 }
这个是c++版本的 ,现在正在把这个做成java包以后专用使用
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。