小弟,最近在做一个算式解析的程序

gk0205 2002-01-30 05:51:08
加精
就是给你一个表达式,例如sin(a+(b*a)-b)之类的式子,怎么样把它读出来,转换成前缀或后缀表达式!
...全文
265 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
gk0205 2002-02-26
  • 打赏
  • 举报
回复
结帐
lion1900 2002-02-06
  • 打赏
  • 举报
回复
大开眼界!
Thalses 2002-02-06
  • 打赏
  • 举报
回复
有兴趣的话看一下《编译原理》,上面有完整算法。
aph 2002-02-05
  • 打赏
  • 举报
回复
用yacc/lex,很方便的
微星1234 2002-02-05
  • 打赏
  • 举报
回复
呵呵,我做过的,
先把三角函数等转化成符号,如0x1---sin,0x2----cos,.....
再在转化成后缀式时把0x?的优先级设为最高,
总之就是这个思路啊,如果需要, 我可以给你设计图或原代码。
yuan_zhi_fei 2002-02-05
  • 打赏
  • 举报
回复
这是一个计算表达式的程序,如要转换成前缀表达式,还需要修改
yuan_zhi_fei 2002-02-05
  • 打赏
  • 举报
回复
初学,如有不对,请多指教

#include"stdio.h"
#include"conio.h"
#include"string.h"
#include"stdlib.h"
char optr[20][100];
char opnd[20][100];
char * op="+-*/()=";
int poptr,popnd;
struct pre{
char * op1;
char * op2;
char * p;
};
struct pre pred[46];
char* strsource;
char input[100];
char w[20];
char t[20];
char * temps="=";
void main(){
void inipred();
void inioptr();
void iniopnd();
void push(char *,char*);
char* pop(char *);
void read();
char* gettop(char *);
char* operate(char*,char*,char*);
int exist(char*);
int precede(char*,char*);
char x[2];
char a[20];
char b[20];
unsigned int l;
char* r;
inipred();
inioptr();
iniopnd();
strsource=gets(input);
read();
while (!(strcmp(w,temps)==0 && strcmp(gettop("optr"),temps)==0)){
if (exist(w)==0){
push("opnd",w);
read();
}
else{
switch (precede(gettop("optr"),w)){
case 2:
push("optr",w);
read();
break;
case 3:
r=pop("optr");
for (l=0;l<=strlen(r);l++)
x[l]=*(r+l);
read();
break;
case 1:
r=pop("optr");
for (l=0;l<=strlen(r);l++)
x[l]=*(r+l);
r=pop("opnd");
for (l=0;l<=strlen(r);l++)
b[l]=*(r+l);
r=pop("opnd");
for (l=0;l<=strlen(r);l++)
a[l]=*(r+l);

push("opnd",operate(a,x,b));
break;
}

}
}
printf("\n%8.2f",atof(gettop("opnd")));
getch();
};
void inioptr(){
poptr=0;
optr[poptr][0]='=';
optr[poptr][1]='\0';
};
void iniopnd(){
popnd=-1;
};
void push(char * a,char* b){
char * temp="optr";
unsigned int l;
if (strcmp(a,temp)==0){
poptr++;
for (l=0;l<=strlen(b);l++)
optr[poptr][l]=b[l];
}
else{
popnd++;
for (l=0;l<=strlen(b);l++)
opnd[popnd][l]=b[l];
}
};
char* pop(char* a){
char* temp;
char* te="optr";
if (strcmp(a,te)==0){
temp= optr[poptr];
poptr--;
return temp;
}
else{
temp=opnd[popnd];
popnd--;
return temp;
}
};
void read(){
char b[20]="";
unsigned int l;
int t=0;
if (*strsource=='+'|| *strsource=='-' || *strsource=='*' || *strsource=='/' || *strsource=='(' || *strsource==')' || *strsource=='='){
b[t++]=*strsource;
strsource=strsource+1;
b[t]='\0';
t=0;
}
else
for (l=0;l<strlen(strsource);l++)
if (*(strsource+l)=='+' || *(strsource+l)=='-' || *(strsource+l)=='*' || *(strsource+l)=='/' || *(strsource+l)=='(' ||*(strsource+l)==')' || *(strsource+l)=='='){
strsource=strsource+l;
b[t]='\0';
t=0;
break;
}
else
b[t++]=*(strsource+l);
for (l=0;l<=strlen(b);l++)
w[l]=b[l];
};
char* gettop(char* a){
char * temp="optr";
if (strcmp(a,temp)==0)
return optr[poptr];
else
return opnd[popnd];
};
char * operate(char* a,char * b,char * c){
char *add="+";
char *sub="-";
char *pl="*";
char *change(double);
if (strcmp(b,add)==0) return change(atof(a)+atof(c));
else
if (strcmp(b,sub)==0) return change(atof(a)-atof(c));
else
if (strcmp(b,pl)==0) return change(atof(a)*atof(c));
else
return change(atof(a)/atof(c));
};
char *change(double num){
char * temp;
int d=8;
int a,b,c;
temp=fcvt(num,d,&a,&b);
for (c=strlen(temp)+1;c>=a+1;c--)
temp[c]=temp[c-1];
temp[c]='.';
if (b!=0){
for (c=strlen(temp)+2;c>0;c--)
temp[c]=temp[c-1];
temp[0]='-';
}
return temp;
};
int exist(char * a){
if (strstr(op,a))
return 1;
else
return 0;
};
int precede(char* a,char* b){
int t;
char * dy=">";
char * xy="<";
for (t=0;t<= 45;t++)
if (strcmp(a,pred[t].op1)==0&&strcmp(b,pred[t].op2)==0)
if (strcmp(pred[t].p,dy)==0) return 1;
else
if (strcmp(pred[t].p,xy)==0)
return 2;
else
return 3;
};
void inipred(void){
pred[0].op1="+";
pred[0].op2="+";
pred[0].p=">";
pred[1].op1="+";
pred[1].op2="-";
pred[1].p=">";
pred[2].op1="+";
pred[2].op2="*";
pred[2].p="<";
pred[3].op1="+";
pred[3].op2="/";
pred[3].p="<";
pred[4].op1="+";
pred[4].op2="(";
pred[4].p="<";
pred[5].op1="+";
pred[5].op2=")";
pred[5].p=">";
pred[6].op1="+";
pred[6].op2="=";
pred[6].p=">";
pred[7].op1="-";
pred[7].op2="+";
pred[7].p=">";
pred[8].op1="-";
pred[8].op2="-";
pred[8].p=">";
pred[9].op1="-";
pred[9].op2="*";
pred[9].p="<";
pred[10].op1="-";
pred[10].op2="/";
pred[10].p="<";
pred[11].op1="-";
pred[11].op2="(";
pred[11].p="<";
pred[12].op1="-";
pred[12].op2=")";
pred[12].p=">";
pred[13].op1="-";
pred[13].op2="=";
pred[13].p=">";
pred[14].op1="*";
pred[14].op2="+";
pred[14].p=">";
pred[15].op1="*";
pred[15].op2="-";
pred[15].p=">";
pred[16].op1="*";
pred[16].op2="*";
pred[16].p=">";
pred[17].op1="*";
pred[17].op2="/";
pred[17].p=">";
pred[18].op1="*";
pred[18].op2="(";
pred[18].p="<";
pred[19].op1="*";
pred[19].op2=")";
pred[19].p=">";
pred[20].op1="*";
pred[20].op2="=";
pred[20].p=">";
pred[21].op1="/";
pred[21].op2="+";
pred[21].p=">";
pred[22].op1="/";
pred[22].op2="-";
pred[22].p=">";
pred[23].op1="/";
pred[23].op2="*";
pred[23].p=">";
pred[24].op1="/";
pred[24].op2="/";
pred[24].p=">";
pred[25].op1="/";
pred[25].op2="(";
pred[25].p="<";
pred[26].op1="/";
pred[26].op2=")";
pred[26].p=">";
pred[27].op1="/";
pred[27].op2="=";
pred[27].p=">";
pred[28].op1="(";
pred[28].op2="+";
pred[28].p="<";
pred[29].op1="(";
pred[29].op2="-";
pred[29].p="<";
pred[30].op1="(";
pred[30].op2="*";
pred[30].p="<";
pred[31].op1="(";
pred[31].op2="/";
pred[31].p="<";
pred[32].op1="(";
pred[32].op2="(";
pred[32].p="<";
pred[33].op1="(";
pred[33].op2=")";
pred[33].p="=";
pred[34].op1=")";
pred[34].op2="+";
pred[34].p=">";
pred[35].op1=")";
pred[35].op2="-";
pred[35].p=">";
pred[36].op1=")";
pred[36].op2="*";
pred[36].p=">";
pred[37].op1=")";
pred[37].op2="/";
pred[37].p=">";
pred[38].op1=")";
pred[38].op2=")";
pred[38].p=">";
pred[39].op1=")";
pred[39].op2="=";
pred[39].p=">";
pred[40].op1="=";
pred[40].op2="+";
pred[40].p="<";
pred[41].op1="=";
pred[41].op2="-";
pred[41].p="<";
pred[42].op1="=";
pred[42].op2="*";
pred[42].p="<";
pred[43].op1="=";
pred[43].op2="/";
pred[43].p="<";
pred[44].op1="=";
pred[44].op2="(";
pred[44].p="<";
pred[45].op1="=";
pred[45].op2="=";
pred[45].p="=";
};
starfish 2002-02-04
  • 打赏
  • 举报
回复
TO: elc(酋长) 
我不懂你所说的“深层次的嵌套有点问题”以及“单目的深层运算”有问题是怎么回事?
GZCompiler 2002-02-04
  • 打赏
  • 举报
回复
1.设一个操作数栈与一个运算符栈。
2.然后对一个算式(字符串)从头至尾(从左到右)扫描。
3.如果当前扫描的字符是操作数,则直接入操作数栈。
4.如果当前扫描的字符是运算符,则过程要麻烦一点:要判断该运算符与运算符栈栈顶的运
算符的运算优先级,如果当前的优先级高,则压入运算符栈,如果栈顶的优先级高,则取出
该栈顶运算符并与相应的操作数进行运算,运算结果入操作数栈。
5.如此这般,最后操作数栈中会只剩一个操作数,这个就是最终结果了。
gk0205 2002-02-04
  • 打赏
  • 举报
回复
谢谢大家的集思广益!
jobuson 2002-02-02
  • 打赏
  • 举报
回复
算符优先。。。我倒^&*
elc 2002-02-02
  • 打赏
  • 举报
回复
我写的可以 给你
但是深层次 的 嵌套有点问题
请 海星 指点。
elc 2002-02-02
  • 打赏
  • 举报
回复
我 作的东东 有点问题 ,
我将 SIN 等用 括号处理了 ,也是 双压栈,
但是 单目的 深层运算 经常 出错
一两层没 问题
请高手 指点 。
ni_ch 2002-02-01
  • 打赏
  • 举报
回复
两个栈:操作数栈(s1),操作符栈(s2)
弹出一个操作符,对于二元的来说,相应的从s1弹出两个操作数,计算出结果,结果压入s1.依此类推。
但是细节如下:
对3+2*3
3:压入s1
+:看情况压入s2或者s2.pop
2:压入s1
*:看情况压入s2.pop
3: 压入s1
上面所说的情况这里讲:
我是对各种操作符定义了栈内优先级和栈外优先级,如果操作符a在栈顶,b需要入栈,这时候有两种选择:
1。b入栈
2。a先弹出,b再发出入栈请求(这里的意思是a弹出后,还面临相同的两种选择)
例如:如果3*2+4,
到了这一步:s1(3,2)s2(*)
A)+需要入栈,选择2号选择,先让*出栈,相应的3出栈,2出栈,计算出2*3=6压入s1,
s1(6) s2()
B) +正式入栈
又如:3+2*3
s1(3,2) s2(+)
A) *需要入栈,选择1号选择,入栈

只能说这么多了,希望你懂。
gk0205 2002-02-01
  • 打赏
  • 举报
回复
请你们把思路写一下就好了,因为这里贴程序可能不太方便!我的邮箱是:gksq@jswz.net
starfish 2002-02-01
  • 打赏
  • 举报
回复
如果想要支持sin, cos之类的函数
只要在getToken里面修改一下
并且重新制定函数运算和其他算符之间的优先级即可
starfish 2002-02-01
  • 打赏
  • 举报
回复
// 计算前缀表达式

#include <iostream>
#include <string>
#include <stack>
using namespace std;

const char COMPARE[8][8] = {
{ '>', '>', '<', '<', '<', '>', '>', 'E' },
{ '>', '>', '<', '<', '<', '>', '>', 'E' },
{ '>', '>', '>', '>', '<', '>', '>', 'E' },
{ '>', '>', '>', '>', '<', '>', '>', 'E' },
{ '<', '<', '<', '<', '<', '=', 'E', 'E' },
{ '>', '>', '>', '>', 'E', '>', '>', 'E' },
{ '<', '<', '<', '<', '<', 'E', 'R', 'E' },
{ 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E' }
};

int index(char opr)
{
switch (opr) {
case '+': return 0;
case '-': return 1;
case '*': return 2;
case '/': return 3;
case '(': return 4;
case ')': return 5;
case '#': return 6;
default : return 7;
}
}

char Compare(char x, char y) {
return COMPARE[index(x)][index(y)];
}

struct Token {
string str;
bool isNum;
};

void error() {
cout << "bad input!" << endl;
exit(0);
}

bool isOperator(char ch) {
return ( (ch == '+')
|| (ch == '-')
|| (ch == '*')
|| (ch == '/')
|| (ch == '(')
|| (ch == ')')
|| (ch == '#') );
}

bool getToken(string& exp, Token& tok) {
if (exp.length() == 0) return false;
if ( isOperator(exp[0]) ) {
tok.str = exp[0];
tok.isNum = false;
exp = exp.substr(1);
} else {
int i;
for (i = 1; i < exp.length(); i++) {
if (isOperator(exp[i])) break;
}
tok.isNum = true;
tok.str = exp.substr(0, i);
exp = exp.substr(i);
}
return true;
}

string prefix(string exp)
{
stack<char> oprStack;
stack<string> prefixStack;
Token tok;

exp += '#';
oprStack.push('#');
while ( getToken(exp, tok) ) {
if (tok.isNum) { // the token is a number
prefixStack.push(tok.str);
} else { // the token is a operator
char res;
string pre1, pre2, pre;
do {
res = Compare(oprStack.top(), tok.str[0]);
switch (res) {
case '>': pre1 = prefixStack.top();
prefixStack.pop();
pre2 = prefixStack.top();
prefixStack.pop();
/*
如果要求后缀表达式,只要将下面两句改为:
pre = pre2 + " " + pre1 + " " + oprStack.top();
*/
pre = oprStack.top();
pre += " " + pre2 + " " + pre1;

prefixStack.push(pre);
oprStack.pop();
break;
case '<': oprStack.push(tok.str[0]);
break;
case '=': oprStack.pop();
break;
case 'R': return prefixStack.top();
case 'E': error();
}
} while (res == '>');
}
}
return prefixStack.top();
}

void main()
{
/*
输入:(5+4+(2-(3-(6+4/5))))/(3*(6-2)*(2-7))
输出:/ + + 5 4 - 2 - 3 + 6 / 4 5 * * 3 - 6 2 - 2 7
*/
string exp;
cin >> exp;
cout << prefix(exp) << endl;
}
starfish 2002-02-01
  • 打赏
  • 举报
回复
// 进行+-*/()四则混合运算

#include <iostream>
#include <string>
#include <stack>
using namespace std;

const char COMPARE[8][8] = {
{ '>', '>', '<', '<', '<', '>', '>', 'E' },
{ '>', '>', '<', '<', '<', '>', '>', 'E' },
{ '>', '>', '>', '>', '<', '>', '>', 'E' },
{ '>', '>', '>', '>', '<', '>', '>', 'E' },
{ '<', '<', '<', '<', '<', '=', 'E', 'E' },
{ '>', '>', '>', '>', 'E', '>', '>', 'E' },
{ '<', '<', '<', '<', '<', 'E', 'R', 'E' },
{ 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E' }
};

int index(char opr)
{
switch (opr) {
case '+': return 0;
case '-': return 1;
case '*': return 2;
case '/': return 3;
case '(': return 4;
case ')': return 5;
case '#': return 6;
default : return 7;
}
}

char Compare(char x, char y) {
return COMPARE[index(x)][index(y)];
}

struct Token {
int num;
char opr;
bool isNum;
};

void error(string msg) {
cout << msg << endl;
exit(0);
}

bool isOperator(char ch) {
return ( (ch == '+')
|| (ch == '-')
|| (ch == '*')
|| (ch == '/')
|| (ch == '(')
|| (ch == ')')
|| (ch == '#') );
}

bool getToken(string& exp, Token& tok) {
if (exp.length() == 0) return false;
if ( isOperator(exp[0]) ) {
tok.opr = exp[0];
tok.isNum = false;
exp = exp.substr(1);
} else {
int i;
for (i = 1; i < exp.length(); i++) {
if (isOperator(exp[i])) break;
}
tok.isNum = true;
tok.num = atoi(exp.substr(0, i).c_str());
exp = exp.substr(i);
}
return true;
}

double Calculate(double x, double y, char opr)
{
switch (opr) {
case '+': return x + y;
case '-': return x - y;
case '*': return x * y;
case '/': if (y == 0) {
error("Divided by zero!");
return 0;
} else {
return x / y;
}
default: error("Bad Input."); return 0;
}
}


double Evaluate(string exp)
{
stack<char> oprStack;
stack<double> numStack;
Token tok;

exp += '#';
oprStack.push('#');
while ( getToken(exp, tok) ) {
if (tok.isNum) { // the token is a number
numStack.push(tok.num);
} else { // the token is a operator
char res;
double x, y, z;
do {
res = Compare(oprStack.top(), tok.opr);
switch (res) {
case '>': x = numStack.top();


numStack.pop();
y = numStack.top();
numStack.pop();
z = Calculate(y, x, oprStack.top());
numStack.push(z);
oprStack.pop();
break;
case '<': oprStack.push(tok.opr);
break;
case '=': oprStack.pop();
break;
case 'R': return numStack.top();
case 'E': error("Bad Input.");
}
} while (res == '>');
}
}
return numStack.top();
}

void main()
{
string exp;
cin >> exp;
cout << Evaluate(exp) << endl;
}
WQ 2002-01-31
  • 打赏
  • 举报
回复
www.cfan2000.com
GZCompiler 2002-01-31
  • 打赏
  • 举报
回复
哈哈,我也做过动画演示的,不过现在不在手上。
加载更多回复(8)

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧