中缀表达式计算

  国庆后工作很忙,没什么时间看自己的书了。晚上看数据结构,写一个中缀表达式转换成后缀再进行计算的小程序。中缀转换成后缀的核心代码我没花心思去简化逻辑了,该睡觉了。其中,栈是用数组来实现的。

栈的头文件说明:

stack.h
#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");
}
main.c: 中缀转换为后缀,再进行计算的代码:

#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;
}
测试结果:

代码
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

 

posted @ 2010-10-23 01:14  Linjian  阅读(633)  评论(0编辑  收藏  举报