标签: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