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);
}
}
}