1. 程式人生 > >資料結構之棧實現計算器

資料結構之棧實現計算器

在終端輸入一個表示式(四則運算及括號),計算表示式的值。

calculator.h

#ifndef __CALCULATOR_H__
#define __CALCULATOR_H__

#define TRUE 1
#define FALSE 0

#define MAX 100
typedef int StackNum;

typedef char StackOp;

typedef struct _num
{
	StackNum data;
	struct _num *next;
}Num_node;

typedef struct _op
{
	StackOp data;
	struct _op *next;
}Op_node;

typedef struct _linkStack
{
	Num_node *numtop;
	Op_node *optop;	
}LinkStack;


//建立鏈式棧
LinkStack * Create_Stack ();

//判斷運算元棧空
int StackEmpty_num (LinkStack *s);

//判斷運算子棧空
int StackEmpty_op (LinkStack *s);

//進運算元棧
int Push_num (LinkStack *s,StackNum num);

//進運算子棧
int Push_op (LinkStack *s,StackOp op);

//出操作數棧
int Pop_num (LinkStack *s,StackNum *num);

//出運算子棧
int Pop_op (LinkStack *s,StackOp *op);

//獲取運算子棧頂元素
int GetTop_op (LinkStack *s,StackOp *op);

//比較運算子優先順序
int Cmp_op (LinkStack *s,StackOp op);

//運算
int Operate (LinkStack *s);



//銷燬棧
int Destory(LinkStack *s);


#endif  //__CALCULATOR_H__

calculator.c
#include <stdlib.h>
#include "calculator.h"
#include "error.h"

//建立鏈式棧
LinkStack * Create_Stack ()
{
	LinkStack * s = (LinkStack *)malloc(sizeof(LinkStack)/sizeof(char));
	if (s == NULL)
	{
		errno = MALLOC_ERROR;
		return NULL;
	}
	s->numtop = NULL;
	s->optop = NULL;
	return s;
}

//判斷運算元棧空
int StackEmpty_num (LinkStack *s)
{
	if (s == NULL)
	{
		errno = ERROR;
		return FALSE;
	}
	return s->numtop == NULL;
}

//判斷運算子棧空
int StackEmpty_op (LinkStack *s)
{
	if (s == NULL)
	{
		errno = ERROR;
		return FALSE;
	}
	return s->optop == NULL;
}

//進運算元棧
int Push_num (LinkStack *s,StackNum num)
{
	if (s == NULL)
	{
		errno = ERROR;
		return FALSE;
	}
	Num_node * num_node = (Num_node *)malloc(sizeof(Num_node)/sizeof(char));
	if (num_node == NULL)
	{
		errno = MALLOC_ERROR;
		return FALSE;
	}
	num_node->data = num;
	num_node->next = s->numtop;
	s->numtop = num_node;
	return TRUE;
}

//進運算子棧
int Push_op (LinkStack *s,StackOp op)
{
	if (s == NULL)
	{
		errno = ERROR;
		return FALSE;
	}
	Op_node * op_node = (Op_node *)malloc(sizeof(Op_node)/sizeof(char));
	if (op_node == NULL)
	{
		errno = MALLOC_ERROR;
		return FALSE;
	}
	op_node->data = op;
	op_node->next = s->optop;
	s->optop = op_node;
	return TRUE;
}

//出操作數棧
int Pop_num (LinkStack *s,StackNum *num)
{
	if (s == NULL)
	{
		errno = ERROR;
		return FALSE;
	}
	if (StackEmpty_num (s))
	{
		errno = EMPTY_STACK;
		return FALSE;
	}
	Num_node *p = s->numtop;
	*num = p->data;
	s->numtop = p->next;
	free(p);
	return TRUE;
}

//出運算子棧
int Pop_op (LinkStack *s,StackOp *op)
{
	if (s == NULL)
	{
		errno = ERROR;
		return FALSE;
	}
	if (StackEmpty_op (s))
	{
		errno = EMPTY_STACK;
		return FALSE;
	}
	Op_node *p = s->optop;
	*op = p->data;
	s->optop = p->next;
	free(p);
	return TRUE;
}


//獲取運算子棧頂元素
int GetTop_op (LinkStack *s,StackOp *op)
{
	if (s == NULL)
	{
		errno = ERROR;
		return FALSE;
	}
	if (StackEmpty_op (s))
	{
		errno = EMPTY_STACK;
		return FALSE;
	}
	*op = s->optop->data;
	return TRUE;
}

//比較運算子優先順序
int Cmp_op (LinkStack *s,StackOp op)
{
	if (s == NULL)
	{
		errno = ERROR;
		return FALSE;
	}
	if (StackEmpty_op (s))
	{
		return TRUE;
	}
	StackOp op2;
	GetTop_op (s,&op2);
	switch (op2)
	{
		case '+':
		{
			return TRUE;
		}
		case '-':
		{
			if (op == '-' || op == '+')
			{
				return FALSE;
			}
			return TRUE;
		}
		case '*':
		{
			return FALSE;
		}
		case '/':
		{
			return FALSE;
		}
		default :
			return TRUE;
	}
}

//運算
int Operate (LinkStack *s)
{
	if (s == NULL)
	{
		errno = ERROR;
		return FALSE;
	}
	if (StackEmpty_op (s))
	{
		errno = EMPTY_STACK;
		return FALSE;
	}
	StackOp op;
	Pop_op (s,&op);
	if (op == '(')
	{
		return FALSE;
	}
	StackNum num1,num2;
	Pop_num (s,&num1);
	if (StackEmpty_num (s))
	{
		Push_num (s,num1);
		return FALSE;
	}
	Pop_num (s,&num2);
	StackNum result;
	switch (op)
	{
		case '+':
			result = num2 + num1;
			break;
		case '-':
			result = num2 - num1;
			break;
		case '*':
			result = num2 * num1;
			break;
		case '/':
			result = num2 / num1;
			break;
		default:
			return FALSE;
	}
	Push_num (s,result);
	return TRUE;	
}


//銷燬棧
int Destory(LinkStack *s)
{
	if (s == NULL)
	{
		errno = ERROR;
		return FALSE;
	}
	free(s);
	return TRUE;
}

main.c
#include <stdio.h>
#include "calculator.h"
#include "error.h"
#include <stdlib.h>

int main()
{
	LinkStack *s = Create_Stack ();
	char exp[MAX];
	printf ("input an expression:");
	fgets(exp,MAX,stdin);
	if (exp[0] < '0' || exp[0] > '9')
	{
		if (exp[0] != '(')
		{
			errno = INPUT_ERROR;
			MyError ("fgets:");
			printf ("輸入錯誤,第一個字元應該為數字或“(”\n");
			Destory(s);
			return FALSE;
		}
	}
	int i = 0;
	while (exp[i])
	{
		if (exp[i] == '\n')
		{
			exp[i] = '\0';
			break;
		}
		i++;
	}
	i = 0;
	char *p = exp;
	char *tmp = p;
	int flag = 0;
	while (p[i])
	{
		if (p[i] >= '0' && p[i] <= '9')
		{
			i++;
			flag = 1;
			continue;
		}
		if (flag == 1)
		{
			Push_num (s,atoi(p));
			flag = 0;
		}
		p = &p[i];
		i = 0;
		if (p[i] == '(')
		{
			if (p[i+1] == '+' || p[i+1] == '-' || p[i+1] == '*' || p[i+1] == '/' || p[i+1] == ')')
			{
				errno = INPUT_ERROR;
				MyError ("fgets:");
				Destory(s);
				return FALSE;
			}
			Push_op (s,'(');
		}
		else if (p[i] == ')')
		{
			while (Operate (s));
		}
		else
		{
			if (p[i+1] == '+' || p[i+1] == '-' || p[i+1] == '*' || p[i+1] == '/' || p[i+1] == ')')
			{
				errno = INPUT_ERROR;
				MyError ("fgets:");
				Destory(s);
				return FALSE;
			}
			while (Cmp_op (s,p[i]) != TRUE)
			{
				Operate (s);
			}
			Push_op (s,p[i]);	
		}
		p = &p[i+1];
		tmp = p;
	}
	if (flag == 1)
	{
		Push_num (s,atoi(tmp));
	}
	while (Operate (s));
	StackNum result = 0;
	Pop_num (s,&result);
	printf ("result = %d\n",result);
	Destory(s);

    return 0;
}

此專案未完善的地方還有很多,特別是對一些錯誤輸入的識別與處理。希望與大家一起完善。