ds-lab2(选):字符表达式求值_4(加入乘方、单目减后缀运算符、字符常量、float型英文变量名)
温柔似野鬼°
591次浏览
2020年07月28日 19:32
最佳经验
本文由作者推荐
隗嚣-月儿拼音
# include
# include
# include
char *OP="~^+-*/()#"; //运算字符集合OP,'~'定义为单目减后缀运算符,'^'定义为乘方运算符
char *OT=""; //运算数字符集合OT
typedef struct { //定义结构类型以存放变量名称和数值
char L[11];
float d;
}Node;
Node *H[10]; //定义外部结构指针数组
typedef struct { //定义运算符栈的结构
char *base;
char *top;
int stacksize;
}SqStack_1;
typedef struct { //定义运算数栈的结构
float *base;
float *top;
int stacksize;
}SqStack_2;
SqStack_1 OPTR;SqStack_2 OPND; //定义外部运算符栈OPTR和运算数栈OPND
int InitStack_1 (SqStack_1 *S) { //创建存放运算符的空栈
S->base=(char *)malloc (20*sizeof(char)); //20为初始空间分配量
if (!S->base) exit (-2);
S->top=S->base;
S->stacksize=20;
return 1;
} //InitStack_1
int InitStack_2 (SqStack_2 *S) { //创建存放运算数的空栈
S->base=(float *)malloc (20*sizeof(float)); //20为初始空间分配量
if (!S->base) exit (-2);
S->top=S->base;
S->stacksize=20;
return 1;
} //InitStack_2
char GetTop_1 (SqStack_1 *S) { //取运算符栈的栈顶元素,并直接返回
if (S->top==S->base) {printf ("栈空
");return 'E';}
return *(S->top-1);
} //GetTop_1
float GetTop_2 (SqStack_2 *S) { //取运算数栈的栈顶元素,并直接返回
if (S->top==S->base) {printf ("栈空
");return 'E';}
return *(S->top-1);
} //GetTop_2
int Push_1 (SqStack_1 *S,char e) { //将运算符e压入栈顶
if (S->top-S->base>=S->stacksize) { //空间不足
S->base=(char *)realloc (S->base,(S->stacksize+10)*sizeof(char)); //10为新增空间大小
if (!S->base) exit (-2);
S->top=S->base+S->stacksize;
S->stacksize+=10;
}
*S->top=e;S->top++;return 1;
} //Push_1
int Push_2 (SqStack_2 *S,float e) { //将运算数e压入栈顶
if (S->top-S->base>=S->stacksize) { //空间不足
S->base=(float *)realloc (S->base,(S->stacksize+10)*sizeof(float)); //10为新增空间大小
if (!S->base) exit (-2);
S->top=S->base+S->stacksize;
S->stacksize+=10;
}
*S->top=e;S->top++;return 1;
} //Push_2
char Pop_1 (SqStack_1 *S) { //删除运算符栈的栈顶元素,并直接返回之
if (*(S->top)==*(S->base)) {printf ("栈空
");return 'E';}
S->top--;return *(S->top);
} //Pop_1
float Pop_2 (SqStack_2 *S) { //删除运算数栈的栈顶元素,并直接返回之
if (S->top==S->base) {printf ("栈空
");return 0.0;}
S->top--;return *(S->top);
} //Pop_2
int In_1 (char s) { //字符s是否为运算符:若是,返回1;否则,返回0
int k=0;
while ((s!=OP[k])&&(OP[k]!='0')) k++;
if (OP[k]!='0') return 1;
else return 0;
} //end In_1
int In_2 (char s) { //字符s是否为运算数符:若是,返回1;否则,返回0
int k=0;
while (
(s!=OT[k])&&(OT[k]!='0')) k++;
if (OT[k]!='0') return 1;
else return 0;
} //end In_2
char Preceed (char c1,char c2) { //比较运算符c1和c2的优先级:若c1高,返回字符'>';若c1低,返回字符'<';否则,返回字符'='
char *row,*col;
char opt[9][10]={"@>>>>>@>>","<@>>>><>>","<<>><<<>>","<<>><<<>>","<<>>>><>>","<<>>>><>>","<<<<<<<=@",">>>>>>@>>","<<<<<<<@="};
//用二维字符数组定义运算符的优先级
row=strchr (OP,c1);col=strchr (OP,c2);
return opt[row-OP][col-OP];
} //end Preceed
float StrintToFloat_1 (char *ch,int *f) { //将字符表达式中连续的运算数字符转化为一个float型数
char *p=ch;int *q=f;
float v1,v2,t;
v1=0.0;v2=0.0;t=(float)0.1;
while (In_2 (*p)) {
v1=v1*10+(*p-'0');p++;*q=*q+1;
}
p++;*q=*q+1;
while (In_2 (*p)) {
v2=v2+(*p-'0')*t;t=(float)(t*0.1);p++;*q=*q+1;
}
return v1+v2;
} //end StrintToFloat_1
float StrintToFloat_2 (char *ch,int *f) { //将字符表达式中字符常量转化为一个float型数
char *p=ch;int *q=f;
*q=*q+1;
return (float)(*p);
} //end StrintToFloat_2
float StrintToFloat_3 (char *ch,int *f) { //将字符表达式中float型变量转换为其所对应的float型数
char *p=ch;int *q=f;
char v[11];int u=0,k=0;
while ((!In_1 (*p))&&(!In_2 (*p))) {
v[u]=*p;u++;*q=*q+1;p++;
}
while (k<10) {
u=0;
while ((v[u]==(H[k]->L[u]))&&(u<10)) {u++;}
if (H[k]->L[u]) k++;
else return H[k]->d;
}
} //end StrintToFloat_3
float Operate (float z,char c,float x) { //两数与定义的运算符的操作运算,返回float型的运算结果
if (c=='+') return z+x;
if (c=='-') return z-x;
if (c=='*') return z*x;
if (c=='/') return z/x;
if (c=='^') return (float)(pow (double(z),double(x)));
if (c=='~') return x-1;
else {
printf ("运算符不恰当
");
return 0.0;
}
} //end Operate
float EvaluateExpression (char *s) { //求算字符表达式的值,以float型返回
float a,b;char theta;
InitStack_1 (&OPTR); InitStack_2 (&OPND);
Push_1 (&OPTR,'#'); //字符栈栈底元素置为'#',便于终止运算
int i=0;
while ((s[i]!='#')||(GetTop_1 (&OPTR)!='#')) {
if ((!In_1 (s[i]))&&(!In_2 (s[i]))) {
if ((!In_1 (s[i+1]))&&(!In_2 (s[i+1]))) //float型变量名转换为float型数
Push_2 (&OPND,StrintToFloat_3 (&s[i],&i));
else Push_2 (&OPND,StrintToFloat_2 (&s[i],&i)); //字符型常量转换为float型数
}
else if (In_2 (s[i])) Push_2 (&OPND,StrintToFloat_1 (&s[i],&i)) //连续运算数字符转换为float型数
else
switch (Preceed(GetTop_1 (&OPTR),s[i])) {
case '<': //栈顶运算符优先级低,则运算符进栈
Push_1 (&OPTR,s[i]);i++;break;
case '=': //优先级相同,栈顶运算符为'(',则出栈,去括号
Pop_1 (&OPTR);i++;break;
case '>': //栈顶运算符优先级高,则去运算符和运算数出栈,
进行相应操作,结果入运算数栈
if (((GetTop_1 (&OPTR))=='~')||((GetTop_1 (&OPTR))=='-')) { //单目减运算符操作
theta=Pop_1 (&OPTR);b=Pop_2 (&OPND);a=0.0;
Push_2 (&OPND,Operate (a,theta,b));break;
}
else { //双目运算符操作
theta=Pop_1 (&OPTR);b=Pop_2 (&OPND);a=Pop_2 (&OPND);
Push_2 (&OPND,Operate (a,theta,b));break;
}
} //end switch
} //end while
return GetTop_2 (&OPND);
} //end EvaluateExpression
void main () {
char s[1000]; //字符串存于字符数组s中
int ful,h=0;char y;
printf ("注:变量个数不超过10
"); //结构指针数组空间为10,用于存放的变量个数不能大于10
printf ("请输入表达式中float型变量的个数:");
scanf ("%d",&ful);
while (ful!=0) {
printf ("注:变量名称为2~10个英文字母
"); //结构成员字符数组空间为11,变量名含英文字母个数不能大于10,最后为结束标志
while (h
printf ("请输入第%d个float型变量的名称:",h+1);
scanf ("%s",&(H[h]->L));
printf ("请输入第%d个float型变量的初值:",h+1);
scanf ("%f",&(H[h]->d));
h++;
}
y=H[0]->L[1];
}
printf ("注:字符表达式中连续的数字部分必须有小数点,表达式以'#'结束
"); //由于转换过程中有小数点,故小数点不可省
printf ("请输入字符表达式:"); //数字要有小数点,表达式以'#'结束
scanf ("%s",s);
printf ("表达式结果为:%f
",EvaluateExpression (s));
} //end main
//'~'为单目减后缀运算符,'^'为乘方运算符