棧的應用--簡單計算器---加減乘除
阿新 • • 發佈:2018-12-27
原始檔 1
#include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #define emptytos (-1)//空棧 #define minstacksize (5)//最小棧大小 //typedef char element; #define element int //順序棧的實現 typedef struct stackrecord { int capacity; int topofstack; element *array; }*stack, stackrecord; void calloc_error(const stack s) /** *判斷記憶體分配是否正常 */ { if (s == NULL) { printf("calloc error"); //exit(0); } } void array_error(const element* a) /** *判斷分配是否正常 */ { if (a == NULL) { printf("calloc error"); //exit(0); } } void makeempty(stack s)//使棧為空 /** *使棧為空 */ { s->topofstack = emptytos; } int isempty(const stack s)//判斷棧是否為空 /** *判斷棧是否為空 */ { return s->topofstack == emptytos; } int isfull(const stack s) /** *判斷棧是否滿 */ { return (s->topofstack + 1) >= s->capacity; } int stack_size(const stack s) /** *判斷棧的大小 */ { return s->capacity; } void free_stack(stack s) /** *銷燬棧 */ { if (s != NULL) { free(s->array); free(s); } } stack createstack(const int maxelement) /** *建立棧 */ { stack s; if (maxelement < minstacksize) { printf("maxelement is too small!!"); //exit(1); } s = calloc(1, sizeof(stackrecord)); calloc_error(s); s->array = (element*)calloc(maxelement, sizeof(element)); array_error(s->array); s->capacity = maxelement; makeempty(s); return s; } int error(const char *__format, ...) /** *報錯printf */ { register int __retval; __builtin_va_list __local_argv; __builtin_va_start( __local_argv, __format ); __retval = __mingw_vprintf( __format, __local_argv ); __builtin_va_end( __local_argv ); return __retval; //exit(0); } void push(element data, stack s) /** *進棧 */ { if (isfull(s)) { error("stack is full!error!!"); } else if (s->capacity < 1) { error("stack is not initialize!!"); } else { s->topofstack++; s->array[s->topofstack] = data; } } element top(const stack s) /** *返回棧頂的資料 */ { if (!isempty(s)) { return s->array[s->topofstack]; } error("s is error"); return 0; } void pop(stack s) /** *出棧 */ { if (isempty(s)) { error("stack is empty"); } else { s->topofstack--; } } element top_and_pop(stack s) /** *返回棧頂的資料 並彈出棧 */ { if ((!isempty(s))) { return s->array[s->topofstack--]; } error("s is error"); return 0; } int priority(const char a) /** *算數表示式優先順序 */ { switch (a) { case '+': case '-': return 3; break; case '#': return 0; break; case '*': case '/': case '%': return 4; break; case '(': case ')': return 5; break; } } int char_of_intsize(const char a)//返回給定字元的asill值 { return a - '0'; } void display_stack(const stack s)//顯示棧元素 { int index = s->topofstack; while (index > -1) { printf("%c ", s->array[index--]); } } void display_int_stack(const stack s)//顯示棧元素 { int index = s->topofstack; while (index > -1) { printf("%d ", s->array[index--]); } } extern void infix_to_suffix(const char *s, stack z1, stack z2)//中綴轉字尾 { int b = 0; while (s[b] != '#') { if (char_of_intsize(s[b]) >=0)//如果是運算元 { push(s[b], z1); b++; } else if (isempty(z2))//如果臨時棧為空 { push(s[b], z2); b++; } else { if (priority(z2->array[z2->topofstack]) < priority(s[b]))//如果當前數的優先順序大於棧頂的優先順序 { if (s[b] != ')')//如果當前數不是右圓括號 { push(s[b], z2); b++; } else if (s[b] == ')')//如果當前數是右圓括號 { while (top(z2) != '(')//括號處理 { push(top_and_pop(z2), z1);//括號裡面的操作符 處理 } if (top(z2) == '(')//從臨時棧中彈出 右括號 { pop(z2); } b++; } } else if (priority(z2->array[z2->topofstack]) >= priority(s[b])) { if (z2->array[z2->topofstack] == '(') //如果存在括號 { push(s[b], z2); b++; } else { while (priority(z2->array[z2->topofstack]) >= priority(s[b]) && z2->array[z2->topofstack] != '(') { push(top_and_pop(z2), z1); push(s[b], z2); b++; } } } } } while (!isempty(z2))//臨時棧的資料 放到資料棧 { push(top_and_pop(z2), z1); } while (!isempty(z1))//資料棧的資料 倒序放到 臨時棧 { push(top_and_pop(z1), z2); } } static int operator(const stack s) { return char_of_intsize(s->array[s->topofstack]) < 0; } extern void switch_type_stackrecord(const int type) { switch (type) { case 1://棧資料型別轉換為int #ifdef element #undef element #define element int #else #define element int #endif // element break; case 2://棧資料型別轉換為char #ifdef element #undef element #define element char #else #define element char #endif // element break; case 3://棧資料型別轉換為float #ifdef element #undef element #define element float #else #define element float #endif // element break; case 4://棧資料型別轉換為double #ifdef element #undef element #define element double #else #define element double #endif // element break; default://轉換錯誤 printf("switch_type_stackrecord of the parameter is error !!"); break; } } int calculator(char a, stack s) { int result;//儲存結果 switch (a) { case'-': result = (s->array[s->topofstack - 1]) - (s->array[s->topofstack]); pop(s); pop(s); push(result, s); break; case'+': result = (s->array[s->topofstack - 1]) + (s->array[s->topofstack]); pop(s); pop(s); push(result, s); break; case'*': result = (s->array[s->topofstack - 1]) * (s->array[s->topofstack]); pop(s); pop(s); push(result, s); break; case'/': if ( s->array[s->topofstack] != 0) { result = ( s->array[s->topofstack - 1]) / (s->array[s->topofstack]); } else { result = 0; printf("除數不能為0!"); } pop(s); pop(s); push(result, s); break; case'%': if ( s->array[s->topofstack] != 0) { result = (s->array[s->topofstack - 1] ) % ( s->array[s->topofstack]); } else { result = 0; printf("取餘數不能為0!!"); } pop(s); pop(s); push(result, s); break; default://遇到無法識別的操作符 printf("operator error!!"); return 0; break; } } extern void simple_calculator(stack z1, stack z2) //中綴計算器--簡單 { free_stack(z1);//clean棧 switch_type_stackrecord(1);//棧資料型別換成int z1 = createstack(15);//建立一個數據型別為int的棧 while (!isempty(z2)) { if (!operator(z2))//判斷棧頂是否為運算元 { //printf("s=%d\n",char_of_intsize(top(z2))); push(char_of_intsize(top_and_pop(z2)), z1);//把運算元彈出 並壓入z1棧 } else { calculator(top_and_pop(z2), z1);//遇到操作符 計算 //printf("sum=%d\n",top(z1)); } } free_stack(z2); }
原始檔二
#include "20150518.c" int main() { stack z1, z2; z1 = createstack(15);//資料棧 z2 = createstack(15);//臨時棧 char *s = "2-2*4/(2*0)#";//3*3-3+3*(7-9) infix_to_suffix(&s[0], z1, z2); printf("z2="); display_stack(z2); simple_calculator(z1, z2); printf("\nz1="); display_int_stack(z1); return 0; }