首页 > 代码库 > 编程实现计算器

编程实现计算器

需求

编程实现计算器,当输入一个表达式时,可以得出计算结果。(实现加、减、乘、除、取余以及负号运算)

思路

1. 维护两个栈,一个栈my_dig用于push数字,另一个栈my_op用于push运算符。栈中元素结构如下:

typedef struct tag_stack1{    int dig_arr[1024];    int dig_top;}DIG, *pDIG;typedef struct tag_stack2{    char op_arr[1024];    int  op_top;}OP, *pOP;

2. 遍历表达式字符串,当遇到数字时,将数字push到栈my_dig中,这个没有问题。对于运算符需要讨论:

1)如果运算符是右括号,则my_op需要一直弹栈计算,直到左括号出栈。

2)如果运算符不是右括号,则需判断当前运算符与栈顶运算符的优先级高低,如果当前运算符优先级高,则入栈;否则弹栈计算,直到当前运算符优先级低于栈顶运算符优先级为止,此时当前运算符入栈。

注意

需要区分负号与其他运算符。本代码处理负号的入栈时,将其替换成‘@’,以便区分其与减号。

1. 减号与负号,两者优先级不同。

2. 对于负号的计算,每次从数字栈中只取一个操作数,而对于其他运算符(包括减号)的计算,每次从数字栈中需要取两个操作数。

代码

/*************************************************************************  > File Name: main.c  > Author: KrisChou  > Mail:zhoujx0219@163.com   > Created Time: Wed 10 Sep 2014 07:44:10 PM CST ************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct tag_stack1{    int dig_arr[1024];    int dig_top;}DIG, *pDIG;typedef struct tag_stack2{    char op_arr[1024];    int  op_top;}OP, *pOP;static int is_ok[8][8] = {    //      + - * / % ( # @ )    /* + */ 0,0,0,0,0,1,1,0,    /* - */ 0,0,0,0,0,1,1,0,    /* * */ 1,1,0,0,0,1,1,0,    /* / */ 1,1,0,0,0,1,1,0,    /* % */ 1,1,0,0,0,1,1,0,    /* ( */ 1,1,1,1,1,1,1,1,    /* # */ 0,0,0,0,0,0,0,0,    /* @ */ 1,1,1,1,1,1,1,0};static char op_arr[9] = {+,-,*,/,%,(,#,@,)};static int find_index(char op){    int index;    for(index = 0; index < 9; index++)    {        if(op == op_arr[index])        {            return index;        }    }    return -1;}static int is_myspace(char c){    if(c ==   || c == \n || c == \t || c == \v)    {        return 1;    }else    {        return 0;    }}static void trim_space(char *str){    int slow = -1;    int fast = 0;    while(str[fast] != \0)    {        if(!is_myspace(str[fast]))        {            str[++slow] = str[fast];        }        fast++;    }    str[++slow] = \0;}static int calculate(char op, int left, int right){    switch(op)    {        case(+):return left + right;break;        case(-):return left - right;break;        case(*):return left * right;break;        case(/):return left / right;break;        case(%):return left % right;break;    }}int handler(char *str){    OP my_op;    DIG my_dig;      memset(&my_op,0,sizeof(OP));    memset(&my_dig,0,sizeof(DIG));      //两个栈,栈顶元素均指向下一个要入栈的位置    my_op.op_arr[my_op.op_top++] = #;    int result = 0;    int index  = 0;    for( index = 0; str[index] != \0; index++ )    {        int numb;        if( find_index(str[index]) >= 0 && find_index(str[index] <= 8)) /* 操作符 */        {            int left,right;            char stk_op;            int tmp_result;            if(str[index] == ))                {                while(my_op.op_arr[my_op.op_top-1] != ()                {                    stk_op = my_op.op_arr[--my_op.op_top];                    right  = my_dig.dig_arr[--my_dig.dig_top];                    if(stk_op == @)                    {                        tmp_result = -right;                        }else                    {                        left   = my_dig.dig_arr[--my_dig.dig_top];                        tmp_result = calculate(stk_op, left, right);                    }                    my_dig.dig_arr[my_dig.dig_top++] = tmp_result;  //新操作数入栈                }                my_op.op_top--;//‘(‘也出栈            }else            {                            if(      //操作符为负号                         str[index] == - &&                         ( (index > 0 && find_index(str[index-1])>=0 && find_index(str[index-1])<=4) ||                           (index > 0 && str[index-1] == ()                                        ||                          (index > 0 && str[index-1] == @)                                        ||                          (index == 0 )                        )                                                                                                 )                {                    str[index] = @;                }                                while(1)                {                    stk_op = my_op.op_arr[my_op.op_top-1];                    if( is_ok[find_index(str[index])][find_index(stk_op)] ) //运算符可以进栈                    {                        my_op.op_arr[my_op.op_top++] = str[index];                        break;                    }else                    {                        my_op.op_top--;                        right  = my_dig.dig_arr[--my_dig.dig_top];                        if(stk_op == @)                        {                            tmp_result = -right;                        }else                        {                            left   = my_dig.dig_arr[--my_dig.dig_top];                            tmp_result = calculate(stk_op, left, right);                        }                        my_dig.dig_arr[my_dig.dig_top++] = tmp_result;  //新操作数入栈                    }                }            }        }else                             /* 操作数 */        {            numb = 0;            while(str[index] >= 0 && str[index] <= 9)            {                numb = numb * 10 + str[index] - 0;                index++;            }            my_dig.dig_arr[my_dig.dig_top++] = numb;            index--;        }    }    while(my_op.op_arr[my_op.op_top-1] != #)    {        int stk_op = my_op.op_arr[--my_op.op_top];        int right  = my_dig.dig_arr[--my_dig.dig_top];        int tmp_result;        int left;        if(stk_op == @)        {            tmp_result = -right;        }else        {            left   = my_dig.dig_arr[--my_dig.dig_top];            tmp_result = calculate(stk_op, left, right);        }        my_dig.dig_arr[my_dig.dig_top++] = tmp_result;  //新操作数入栈    }    result = my_dig.dig_arr[--my_dig.dig_top];    return result;}int main(int argc, char *argv[]){    int ret;    char str[1024];    while(fflush(stdin),memset(str,0,1024),fgets(str,1024,stdin))    {        trim_space(str);        ret = handler(str);        printf("the result is %d\n", ret);    }    return 0;}
 

编程实现计算器