1. 程式人生 > >棧的應用--簡單計算器---加減乘除

棧的應用--簡單計算器---加減乘除

原始檔  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;
}