说明
本程序支持括号以及小数计算
基本思想
先将中缀表达式转换为后缀表达式,再求值
中缀转后缀可以借鉴该博文
表达式求值可以借鉴该博文
我的代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define maxsize 100
#define N 7
typedef struct{//运算符栈
char data[maxsize];
int top;
}seqOperate;
typedef struct{//运算数栈
double data[maxsize];
int top;
}seqData;
char operators[maxsize] = { '+', '-', '*', '/','=','(',')'};
int priotiry(char ch){//运算符优先级
switch(ch){
case '+':
return 1;
case '-':
return 1;
case '*':
return 2;
case '/':
return 2;
case '(':
return 0;
case ')':
return 0;
default:return -1;
}
}
//判断运算符栈是否为空
int isEmptyOp(seqOperate *s1){
if(s1->top == -1)
return 1;
else
return 0;
}
//从运算符栈中弹出一个运算符
char popo(seqOperate *s1){
if(!isEmptyOp(s1)){
char ch=s1->data[s1->top];
s1->top--;
return ch;
}
else
return 'F';
}
//运算符入栈
void pusho(seqOperate *s1,char ch){
s1->top++;
s1->data[s1->top]=ch;
}
//获取栈顶元素
char getTopo(seqOperate *s1){
return s1->data[s1->top];
}
//初始化运算符栈
void initSeqOperate(seqOperate *s1){
//s1=(seqOperate*)malloc(sizeof(seqOperate));
s1->top=-1;
}
//初始化运算数栈
void initSeqData(seqData *s2){
s2->top=-1;
}
//运算数入栈
void pushd(seqData *s2,double d){
s2->top++;
s2->data[s2->top]=d;
}
double popd(seqData *s2){
double d;
d=s2->data[s2->top];
s2->top--;
return d;
}
//判断所给字符是否为运算符
int isOperate(char ch){
int i;
for (i = 0; i < N; i++)
{
if (operators[i] == ch)
{
return 1;
}
}
return 0;
}
char * infixToAffix(char *str){
seqOperate *s1;
int i=0,j=0;
char ch;
static char result[maxsize];
s1=(seqOperate*)malloc(sizeof(seqOperate));//在codeblocks和vc++6.0上都需要这一句,dev-c++上不需要,请视情况而定
// char result[maxsize];
initSeqOperate(s1);
while(str[i]!='\0'){
if(str[i]=='.'||(str[i]<='9'&&str[i]>='0')){
result[j++]=str[i];
}
else{
result[j++]='#';//将数字字符串和操作符分开--转换时定界的功能
if(str[i]=='+'||str[i]=='-'){
if(isEmptyOp(s1)){
pusho(s1,str[i]);
}
else{
while(getTopo(s1)!='('&&!isEmptyOp(s1)){
ch=popo(s1);
result[j++]=ch;
}
pusho(s1,str[i]);
}
}
else if(str[i]==')'){
ch=popo(s1);
while(ch!='('){
result[j++]=ch;
ch=popo(s1);
}
}
else if(str[i]=='*'||str[i]=='/'||str[i]=='('){
pusho(s1,str[i]);
}
}
i++;
}
while(!isEmptyOp(s1)){
ch=popo(s1);
result[j++]=ch;
}
// printf("-------\n");
// printf("%s\n",result);
return result;
}
double getAffixValue(char *res){
seqData *s2;
double sum,t,a,b,result;
int i=0;
s2=(seqData *)malloc(sizeof(seqData));
initSeqData(s2);
while(res[i]!='\0'){
if(res[i]<='9'&&res[i]>='0'){
sum=0;
t=10;
sum=res[i]-'0';
i++;
while((res[i]<='9'&&res[i]>='0')||res[i]=='.'){//字符串转double
if(res[i]!='.'){
if( t == 10)
sum = sum * t + res[i] - 48;
else
{
sum += ( res[i] - 48 ) * t;
t = t*0.1;
}
}
else{
t=0.1;
}
i++;
}
// printf("%lf %d\n",sum,i);
pushd(s2,sum);
}
if(res[i]=='+'||res[i]=='-'||res[i]=='*'||res[i]=='/'){
a=popd(s2);
b=popd(s2);
if(res[i]=='+')
pushd(s2,b+a);
if(res[i]=='-')
pushd(s2,b-a);
if(res[i]=='*')
pushd(s2,b*a);
if(res[i]=='/')
pushd(s2,b/a);
}
i++;
}
result=popd(s2);
//printf("最终结果为:%lf",result);
return result;
}
int main(){
int n,m;
char * res;
char str[maxsize];
double result;
scanf("%d",&n);
while(n--){
scanf("%s",str);
res = infixToAffix(str);
//printf("result%s\n",res);
result=getAffixValue(res);
m=(int)result;
if(result-m==0)
printf("%d\n",m);
else
printf("%.2lf\n",result);
}
}
ps:欢迎评论指正