中缀表达式计算
国庆后工作很忙,没什么时间看自己的书了。晚上看数据结构,写一个中缀表达式转换成后缀再进行计算的小程序。中缀转换成后缀的核心代码我没花心思去简化逻辑了,该睡觉了。其中,栈是用数组来实现的。
栈的头文件说明:
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
#ifndef _STACK_H
#define _STACK_H
typedef int ElementType;
struct StackRecord;
typedef struct StackRecord *Stack;
int IsEmpty(Stack s);
Stack CreateStack(void);
void DestroyStack(Stack s);
void MakeEmpty(Stack s);
void Push(ElementType x, Stack s);
ElementType Pop(Stack s);
ElementType Top(Stack s);
void PrintStack(Stack s);
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "stack.h"
#define MAXSIZE 100
#define SAFE_FREE(s) {if (s) {free(s); s = NULL;} }
struct StackRecord
{
int capacity;
int topOfStack;
ElementType *array;
};
int IsEmpty(Stack s)
{
return s->topOfStack == -1;
}
Stack CreateStack(void)
{
Stack s = malloc(sizeof(struct StackRecord));
if (s == NULL)
{
fprintf(stderr, "create stack failed");
return NULL;
}
s->array = malloc(MAXSIZE * sizeof(ElementType));
if (s->array == NULL)
{
fprintf(stderr, "create stack failed");
return NULL;
}
s->capacity = MAXSIZE;
s->topOfStack = -1;
return s;
}
void DestroyStack(Stack s)
{
if (s == NULL)
{
fprintf(stderr, "[DestroyStack] stack is empty");
return;
}
SAFE_FREE(s->array);
SAFE_FREE(s);
}
void MakeEmpty(Stack s)
{
memset(s->array, 0x00, sizeof(s->array));
s->topOfStack = -1;
}
void Push(ElementType x, Stack s)
{
if (s == NULL)
{
fprintf(stderr, "[Push] stack is empty");
return;
}
if ((s->topOfStack + 1) == s->capacity)
{
fprintf(stderr, "stack is full.");
return;
}
s->topOfStack++;
s->array[s->topOfStack] = x;
}
ElementType Pop(Stack s)
{
if (s->topOfStack == -1)
{
fprintf(stderr, "[Pop] stack is empty.");
return -1;
}
ElementType topValue = s->array[s->topOfStack];
s->array[s->topOfStack] = 0;
s->topOfStack--;
return topValue;
}
ElementType Top(Stack s)
{
if (s->topOfStack == -1)
{
fprintf(stderr, "[Top] stack is empty.");
return -1;
}
return s->array[s->topOfStack];
}
void PrintStack(Stack s)
{
if (s == NULL || s->topOfStack == -1)
{
fprintf(stderr, "[PrintStack] stack is empty.");
return;
}
for (int i = 0; i <= s->topOfStack; ++i)
{
printf("%c ", s->array[i]);
}
printf("\n");
}
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "stack.h"
#define MAXSIZE 100
#define and &&
#define or ||
typedef struct _symbol_level
{
char symbol;
int level;
} SymbolLevel;
SymbolLevel symbol_level[] =
{
{'+', 1}, {'*', 2}, {'(', 3}
};
static int GetSymbolLevel(const char symbol)
{
int len = sizeof(symbol_level) / sizeof(SymbolLevel);
for (int i = 0; i < len; ++i)
{
if (symbol == symbol_level[i].symbol)
{
return symbol_level[i].level;
}
}
return -1;
}
static int InfixToPostfix(const char *infix, int infixLen, char *post, int maxSize)
{
int postIndex = 0;
Stack s = CreateStack();
for (int i = 0; i < infixLen; ++i)
{
if (isdigit(infix[i]) )
{
post[postIndex++] = infix[i];
}
else if ((infix[i] == '+') or (infix[i] == '*') or (infix[i] == '('))
{
if ((IsEmpty(s)) or
((GetSymbolLevel(infix[i]) > GetSymbolLevel(Top(s))) and (Top(s) != '(')) )
{
Push(infix[i], s);
PrintStack(s);
}
else if (GetSymbolLevel(infix[i]) < GetSymbolLevel(Top(s)) and (Top(s) != '('))
{
post[postIndex++] = Pop(s);
if (GetSymbolLevel(infix[i]) == GetSymbolLevel(Top(s)))
{
post[postIndex++] = infix[i];
}
else if (Top(s) == '(')
{
Push(infix[i], s);
}
}
else if (Top(s) == '(')
{
Push(infix[i], s);
PrintStack(s);
}
else
{
post[postIndex++] = infix[i];
}
}
else if (infix[i] == ')')
{
int Tmp;
while ( ((Tmp = Pop(s)) != '(') and (!IsEmpty(s)))
{
post[postIndex++] = Tmp;
}
}
}
while (!IsEmpty(s))
{
post[postIndex++] = Pop(s);
}
DestroyStack(s);
return postIndex > maxSize ? -1 : postIndex;
}
static int ComputeExpression(const char *expression)
{
int leftVal, rigthtVal, result;
Stack s = CreateStack();
for (int i = 0; i < strlen(expression); ++i)
{
if (isdigit(expression[i]))
{
Push(expression[i] - 0x30, s);
}
else
{
leftVal = Pop(s);
rigthtVal = Pop(s);
switch (expression[i])
{
case '*':
result = leftVal * rigthtVal;
break;
case '+':
result = leftVal + rigthtVal;
break;
default:
printf("error symbole '%d'.\n", expression[i]);
break;
}
Push(result, s);
}
}
result = Top(s);
DestroyStack(s);
return result;
}
int main(int argc, char *argv[])
{
char infix[MAXSIZE] = {0};
char postfix[MAXSIZE] = {0};
while (1)
{
printf("enter a infix expression('quit' to exit):\n");
memset(infix, 0x00, sizeof(infix));
fgets(infix, MAXSIZE, stdin);
infix[strlen(infix)] = 0x00;
if (memcmp(infix, "quit", 4) == 0)
{
break;
}
else
{
memset(postfix, 0x00, sizeof(postfix));
InfixToPostfix(infix, strlen(infix), postfix, MAXSIZE);
printf("postfix expression: %s\n", postfix);
printf("result = %d\n", ComputeExpression(postfix));
}
}
return 0;
}
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
ken@Linux:~/DSAA/chap3/stack_infix$ ./stack
enter a infix expression('quit' to exit):
1+2*3+(4*5+6)
+
+ *
+ (
+ ( *
postfix expression: 123*+45*6++
result = 33
enter a infix expression('quit' to exit):
1+2*3+(4*5+6)*2
+
+ *
+ (
+ ( *
+ *
postfix expression: 123*+45*6+2*+
result = 59
enter a infix expression('quit' to exit):
(1+2)+(3+4)
(
( +
+
+ (
+ ( +
postfix expression: 12+34++
result = 10
enter a infix expression('quit' to exit):
1+2*3+(4+5*2)+3
+
+ *
+ (
+ ( +
+ ( + *
postfix expression: 123*+452*++3+
result = 24
enter a infix expression('quit' to exit):
quit