码迷,mamicode.com
首页 > 其他好文 > 详细

编程实现计算器

时间:2014-09-11 15:18:52      阅读:240      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   io   ar   for   2014   div   问题   

需求

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

思路

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

编程实现计算器

标签:style   blog   color   io   ar   for   2014   div   问题   

原文地址:http://www.cnblogs.com/jianxinzhou/p/3966405.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!