计算器目前只需要支持单位正整数的加、减、乘、除运算,并支持用括号表示优先级别。
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct
{
char factor;
int pri;
} FAC;
int compute(char *after)
{
int stack[501], top = -1, i, tmp = 0;
char *a = after;
int divider = 0;
if (NULL == after||strlen(after) > 1000)
return -1;
for (i = 0; i < strlen(a);++i)
{
if (a[i] >= '0'&&a[i] <= '9')
{
tmp = tmp*10 + a[i] - '0';
if (a[i+1] < '0'||a[i+1] > '9')
{
stack[++top] = tmp;
}
continue;
}
switch (a[i])
{
case ' ':
break;
case '+':
tmp = stack[top] + stack[top-1];
stack[--top] = tmp;
break;
case '-':
tmp = stack[top-1] - stack[top];
stack[--top] = tmp;
break;
case '*':
tmp = stack[top] * stack[top-1];
stack[--top] = tmp;
break;
case '/':
// printf("devider is %d/n", stack[top]);
divider = stack[top];
assert(divider != 0);
tmp = stack[top-1] / stack[top];
stack[--top] = tmp;
break;
}
tmp = 0;
}
return stack[0];
}
int priority(char factor)
{
int pri = 0;
switch (factor)
{
case '+': pri = 20;
break;
case '-': pri = 20;
break;
case '*': pri = 50;
break;
case '/': pri = 50;
break;
default:
pri = -1;
}
return pri;
}
int expr(char *e)
{
char after[1001] = {0};
int ia = 0;
int start = 0;
int i;
int len = 0;
FAC tmp = {0};
FAC stack[501] = {0};
int top = 0;
int base = 100;
stack[top].pri = 1000;
if (NULL == e||strlen(e) > 1000)
return -1;
for (i = 0;i < strlen(e);++i)
{
if (e[i] >= '0'&&e[i] <= '9')
{
if (0 == len)
start = i;
++len;
continue;
}
switch (e[i])
{
case ' ':
break;
case '(':
base += 80;
break;
case ')':
base -= 80;
break;
default:
tmp.factor = e[i];
tmp.pri = priority(e[i]);
if (-1 == tmp.pri)
return -1;
tmp.pri += base--;
strncpy(after + ia, e + start, len);
ia += len;
len = 0;
while (top > 0&&tmp.pri <= stack[top].pri)
after[ia++] = stack[top--].factor;
memcpy(&stack[++top], &tmp, sizeof(FAC));
tmp.pri = 0;
after[ia++] = ' ';
}
}
strncpy(after + ia, e + start, len);
ia += len;
len = 0;
while (top > 0)
after[ia++] = stack[top--].factor;
// printf("after: %s/n", after);
return compute(after);
}
int main()
{
char in[1001] = {0};
printf("1 = %d/n", expr("1"));
assert(expr("1") == 1);
printf("1+2 = %d/n", expr("1+2"));
assert(expr("1+2") == 3);
printf("3-2 = %d/n", expr("3-2"));
assert(expr("3-2") == 1);
printf("1+2+3 = %d/n", expr("1+2+3"));
assert(expr("1+2+3") == 6);
printf("1+2-3 = %d/n", expr("1+2-3"));
assert(expr("1+2-3") == 0);
printf("(1+2)-3 = %d/n", expr("(1+2)-3"));
assert(expr("(1+2)-3") == 0);
printf("3-2-1 = %d/n", expr("3-2-1"));
assert(expr("3-2-1") == 0);
printf("3-2*4 = %d/n", expr("3-2*4"));
assert(expr("3-2*4") == -5);
printf("3-(2-1) = %d/n", expr("3-(2-1)"));
assert(expr("3-(2-1)") == 2);
printf("3*(3-1) = %d/n", expr("3*(3-1)"));
assert(expr("3*(3-1)") == 6);
printf("4/(3-1) = %d/n", expr("4/(3-1)"));
assert(expr("4/(3-1)") == 2);
printf("4/(1-1) = %d/n", expr("4/(1-1)"));
// assert(expr("4/(1-1)") == 1);
/* do */
/* { */
/* scanf("%s", in); */
/* if ('0' == in[0]&&0 == in[1]) */
/* break; */
/* printf("%s = %d/n", in, expr(in)); */
/* } */
/* while (1); */
return 1;
}