通过学习《大话数据结构》,练习对栈的使用,此测试是四则运算表达式求值。
先来main函数:
int main()
{
char zhongzhui[30+2] = {};
char houzhui[30+2] = {};
float result = 0.0;
printf("请输入要计算的式子:\n");
fgets(zhongzhui,30,stdin);
zhongzhui[strlen(zhongzhui) - 1] = '\0';
zhuanhuanFloat(zhongzhui,houzhui);
printf("*%s*\n",houzhui);
jisuanFloat(houzhui,&result);
printf("%f",result);
return 0;
}
首先通过中缀表达式转换成后缀表达式,函数如下:
void zhuanhuanFloat(char zhongzhui[], char houzhui[])
{
LinkStack S;
S.top = NULL;
S.count = 0;
int i = 0;
int j = 0;
char tmp;
while(zhongzhui[i]!='\0')
{
if((zhongzhui[i] >= '0') && (zhongzhui[i] <= '9'))
{
while(((zhongzhui[i] >= '0') && (zhongzhui[i] <= '9')) || zhongzhui[i] == '.')
{
houzhui[j] = zhongzhui[i];
j++;
i++;
}
houzhui[j] = ' ';
j++;
}
if((zhongzhui[i] == '*') || (zhongzhui[i] == '/') || (zhongzhui[i] == '('))
{
push(&S,zhongzhui[i]);
//continue;
}
if(zhongzhui[i] == ')')
{
while(S.top->data != '(')
{
pop(&S,&houzhui[j]);
j++;
houzhui[j] = ' ';
j++;
}
pop(&S,&tmp);
//continue;
}
if((zhongzhui[i] == '+') || (zhongzhui[i] == '-'))
{
if(S.top != NULL)
{
if((S.top->data == '*') || (S.top->data == '/'))
{
while(S.top != NULL)
{
pop(&S,&houzhui[j]);
j++;
houzhui[j] = ' ';
j++;
}
push(&S,zhongzhui[i]);
}
else
{
push(&S,zhongzhui[i]);
}
}
else
{
push(&S,zhongzhui[i]);
}
}
i++;
}
while(S.top != NULL)
{
pop(&S,&houzhui[j]);
j++;
houzhui[j] = ' ';
j++;
}
houzhui[j] = '\0';
}
其中对LinkStack的定义:
typedef char SElemType;
typedef struct StackNode
{
SElemType data;
struct StackNode *next;
}StackNode,*LinkStackPtr;
typedef struct LinkStack
{
LinkStackPtr top;
int count;
}LinkStack;
对这个栈操作的函数定义:
void push(LinkStack *S, SElemType e)
{
LinkStackPtr s = NULL;
s = (LinkStackPtr) malloc(sizeof(StackNode));
s->data = e;
s->next = S->top;
S->top = s;
S->count++;
}
void pop(LinkStack *S, SElemType *e)
{
LinkStackPtr p = NULL;
*e = S->top->data;
p = S->top;
S->top = S->top->next;
free(p);
p = NULL;
S->count--;
}
通过转换的输入输出为:
void jisuanFloat(char houzhui[],float *result)
{
LinkStackFloat Sint;
Sint.top = NULL;
Sint.count = 0;
int i = 0;
float e = 0;
while(houzhui[i] != '\0')
{
if(houzhui[i] == ' ')
{
i++;
}
if((houzhui[i] >= '0') && (houzhui[i] <= '9'))
{
e = atof((houzhui + i));
pushFloat(&Sint,e);
while(houzhui[i] != ' ')
{
i++;
}
}
if((houzhui[i] == '+') || (houzhui[i] == '*'))
{
float p,q,r;
popFloat(&Sint,&p);
popFloat(&Sint,&q);
if((houzhui[i] == '+'))
{
r = p + q;
}
else
{
r = p * q;
}
pushFloat(&Sint,r);
}
if((houzhui[i] == '/') || (houzhui[i] == '-'))
{
float p,q,r;
popFloat(&Sint,&p);
popFloat(&Sint,&q);
if((houzhui[i] == '-'))
{
r = q - p;
}
else
{
r = q / p;
}
pushFloat(&Sint,r);
}
i++;
}
popFloat(&Sint,result);
}
typedef struct StackNodeFloat
{
float data;
struct StackNodeFloat *next;
}StackNodeFloat,*LinkStackPtrFloat;
typedef struct LinkStackFloat
{
LinkStackPtrFloat top;
int count;
}LinkStackFloat;
对LinkStackFloat操作函数定义为:
void pushFloat(LinkStackFloat *S, float e)
{
LinkStackPtrFloat s = NULL;
s = (LinkStackPtrFloat) malloc(sizeof(StackNodeFloat));
s->data = e;
s->next = S->top;
S->top = s;
S->count++;
}
void popFloat(LinkStackFloat *S, float *e)
{
LinkStackPtrFloat p = NULL;
*e = S->top->data;
p = S->top;
S->top = S->top->next;
free(p);
p = NULL;
S->count--;
}
从上面可以看出对两个栈的操作是一样的,就是栈数据类型不一下。