《数据结构》-写的一个后缀表达式计算器程序

mystack.h

#define MAX_LEN 30
#define NO_ERR 0	//没有错误

#define ERR_STK_FULL -1 //堆栈已满
#define ERR_STK_EMPTY -2	//堆栈空

#define TYPE_SYMBOL 0
#define TYPE_NUMBER 1


typedef struct stack_t{
	int stack[MAX_LEN];
	char type[MAX_LEN];
	unsigned int top;	
}Stack;


/************************************************************************/
/* 初始化堆栈                                                                     */
/************************************************************************/
void init(Stack *stk){
	stk->top = -1;
}

/************************************************************************/
/* 获取堆栈顶端数据                                                                     */
/************************************************************************/
int get_top_elem(Stack *stk){
	if(stk->top == -1){
		return ERR_STK_EMPTY;
	}
	return stk->stack[stk->top];
}
/************************************************************************/
/* 获取顶端数据类型                                                                     */
/************************************************************************/
char get_top_type(Stack *stk){
	if (stk->top == -1){
		return ERR_STK_EMPTY;
	}
	return stk->type[stk->top];
}
/************************************************************************/
/* 将elem压入堆栈                                                                     */
/************************************************************************/
int push(Stack *stk, int elem, char type){
	if (stk->top == MAX_LEN-1){
		return ERR_STK_FULL;
	}
	(stk->top)++;
	stk->stack[stk->top] = elem;
	stk->type[stk->top]=type;
	return NO_ERR;
}


/************************************************************************/
/*从堆栈中弹出一个元素                                                                     */
/************************************************************************/
int pop(Stack *stk){
	if (stk->top == -1){
		return ERR_STK_EMPTY;
	}
	(stk->top)--;
	return NO_ERR;
}

/************************************************************************/
/* 判断堆栈是否为空                                                      */
/************************************************************************/
bool is_empty(Stack *stk){
	return stk->top == -1 ? true:false;
}
void print_stack(Stack *stk){
	unsigned int i = 0;
	for (i = 0; i <= stk->top; i++){
		if (stk->type[i] == TYPE_NUMBER){
			printf("%d ", stk->stack[i]);
		}else
			printf("%c ",(char)(stk->stack[i]));
	}
	printf("\n");
}

Stack *reverse(Stack *stk){
	Stack *ret = (Stack*)malloc(sizeof(Stack));
	if (ret == NULL) return NULL;
	unsigned int i = 0;
	unsigned int t = stk->top;
	for (; i <= stk->top; i++){
		ret->stack[i] = stk->stack[t-i];
		ret->type[i] = stk->type[t-i];
	}
	ret->top = t;
	return ret;
}







// calculator.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include "mystack.h"

void gen_suffix();
int compare_prio(char,char);
bool isnumber(char);
int strlength(char*);
int calculate();

/*
* 算符的优先级表,依次是
(  )   *   +   NULL   -   NULL  /  
40 41  42  43   44    45  46    47
*这样使得它们与自己代表的ASCII码相对应
*/
unsigned char prio_table[8]={0,1,2,1,0,1,0,2};
Stack sym_stack;
Stack new_exp;
char org_exp[15];


int _tmain(int argc, _TCHAR* argv[])
{
	//printf("input expression:");
	FILE *fp;
	fp = fopen("in.txt","r");
	if (fp != NULL)
		fscanf(fp,"%s",org_exp);	
	gen_suffix();
	print_stack(&new_exp);
	int ret = calculate();
	printf("%d\n", ret);
	system("pause");
	return 0;
}

/************************************************************************/
/* 比较两个符号的优先级,如果a>b 返回正数,a=b,返回0,a<b返回负数      */
/************************************************************************/
int compare_prio(char a, char b){
	//两个字符先需要转换
	if (a == '='){
		a = ')';
	}else if (a == '#'){
		a = '(';
	}
	if (b == '='){
		b = ')';
	}else if (b == '#'){
		b = '(';
	}
	return prio_table[a-40]-prio_table[b-40];
}

/************************************************************************/
/* 判断一个字符否是数字字符                                             */
/************************************************************************/
bool isnumber(char a){
	if (a >= '0'&& a <= '9')
		return true;
	return false;
}

/************************************************************************/
/* 获取字符串str的长度                                                  */
/************************************************************************/
int strlength(char *str){
	if (str == NULL){
		return 0;
	}
	int i = 0;
	while(*str != '\0'){
		i++;
		str++;
	}
	return i;

}

/************************************************************************/
/* 生成后缀表达式,存储在栈new_stack中                                  */
/************************************************************************/
void gen_suffix(){
	init(&sym_stack);
	push(&sym_stack,(int)'#',TYPE_SYMBOL);//开始符入栈
	init(&new_exp);
	int pos = 0;
	int len = strlength(org_exp); //获取长度
	while(pos < len)
	{
		if (isnumber(org_exp[pos])){
			char tmp_str[MAX_LEN];
			int i = 0;
			while (pos < len && isnumber(org_exp[pos])){				
				tmp_str[i++] = org_exp[pos++];
			}
			tmp_str[i] = '\0';
			int number = atoi(tmp_str);
			push(&new_exp, number, TYPE_NUMBER);
		}else{
			char top_sym = (char)get_top_elem(&sym_stack);//获取最顶上的元素
			while (compare_prio(top_sym, org_exp[pos]) >= 0){ //栈顶优先级高于当前运算符
				push(&new_exp, top_sym,TYPE_SYMBOL);
				pop(&sym_stack);					
				top_sym = (char)get_top_elem(&sym_stack);
			}
			push(&sym_stack,org_exp[pos],TYPE_SYMBOL);
			pos++;
		}
		if ((get_top_elem(&sym_stack) == '=')){ //等号意味终结
			pop(&sym_stack);
			push(&new_exp, '=', TYPE_SYMBOL);
			break;
		}
	}
}

int calculate(){
	Stack *rvs_exp = reverse(&new_exp);//反转栈
	init(&new_exp);
	if (reverse == NULL){
		return -9999;
	}
	print_stack(rvs_exp);
	while (!is_empty(rvs_exp)){
		char top_type = get_top_type(rvs_exp);
		char top_ele = get_top_elem(rvs_exp);
		if (top_type == TYPE_NUMBER){
			push(&new_exp, top_ele, top_type);
			pop(rvs_exp);
		}else if (top_type == TYPE_SYMBOL){
			if (top_ele == '='){
				if (!is_empty(&new_exp))
					return get_top_elem(&new_exp);
				else
					return -99999; //error
			}
			int b = get_top_elem(&new_exp);
			pop(&new_exp);
			int a = get_top_elem(&new_exp);
			pop(&new_exp);
			int c;

			switch(top_ele){
				case '+':c = a + b; 
					break;
				case '-': c = a - b;
					break;
				case '*': c= a *b;
					break;
				case '/': c = a / b;
					break;
			}
			push(&new_exp, c, TYPE_NUMBER);
			pop(rvs_exp);
		}

	}
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值