用栈实现了表达式的运算,基本功能可以实现,enhance 给QA测试一下应该可以做个简单的计算器。
root@ubuntu:data-struct# cat stack_cal.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int element_t;
typedef struct {
int top;
int cap;
element_t * data;
} Stack_t, *Stack_ptr;
Stack_ptr new_stack(int cap)
{
Stack_ptr p1 = NULL;
if (cap <= 2) return NULL;
p1 = malloc(sizeof(Stack_t));
if (p1) {
p1->top = -1;
p1->cap = cap;
p1->data = malloc(sizeof(element_t) * cap);
if (!p1->data) {
free(p1);
return NULL;
}
}
return p1;
}
void destroy_stack(Stack_ptr p)
{
if (p) {
free(p->data);
free(p);
}
}
//p must not be empty,
element_t stack_get_top(Stack_ptr p)
{
return p->data[p->top];
}
//只是为了能够让一个stack成为输入才(从0读取,而不是pop)用到这个函数。
element_t stack_get_pos(Stack_ptr p, int pos)
{
if (pos > -1 && pos <= p->top ) {
return p->data[pos];
}
else {
printf("out of range!\n");
}
}
element_t stack_pop(Stack_ptr p)
{
if (p && p->top >= 0) {
p->top--;
return p->data[p->top+1];
}
else {
printf("error pop an empty stack!\n");
return -1;
}
}
int stack_push(Stack_ptr p, element_t e)
{
if (p && (p->cap > p->top + 1)) {
p->data[++p->top] = e;
}
else {
printf("push erro:%s\n", !p ? "null stack input" : "not place to save");
return -1;
}
return 0;
}
int stack_is_empty(Stack_ptr p)
{
return p->top == -1 ? 1 : 0;
}
int stack_clean(Stack_ptr p)
{
if (p) {
p->top = -1;
}
return 0;
}
int stack_number(Stack_ptr p)
{
return p->top + 1;
}
int oper_map(char c)
{
switch (c) {
case '/':
case '*':
return 5;
break;
case '+':
case '-':
return 6;
break;
case '(':
return 4;
break;
default :
return 0;
}
return 0;
}
int cmp_oper(char c1, char c2)
{
int d1 = oper_map(c1);
int d2 = oper_map(c2);
return d1 - d2;
}
int cal(int a1, int a2, char oper)
{
switch (oper) {
case '+' :
return a1 + a2;
break;
case '-':
return a1 - a2;
break;
case '*':
return a1 * a2;
break;
case '/':
return a1 / a2;
break;
default:
printf("Input error operator!!\n");
}
return -1;
}
//输入表达式,计算出值,如:4 + 5 * 1 *(8 - 6 / 2)- 3 = 26。暂不支持幂次方,和两位数(获取数不是本次考查重点)
int main()
{
Stack_ptr p1 = new_stack(256);
Stack_ptr p2 = new_stack(256);
char exp[] = "4+5*1*(8-6/2)-3", *str_p = NULL;
if (!p1 || !p2) {
printf("new stack error!!\n");
exit(-1);
}
//printf("Pls input your expression:");
int exp_len = strlen(exp), i;
str_p = exp;
//将中间表达式转换成后缀表达式:
for (i = 0; i < exp_len; i++) {
if (isdigit(exp[i])) {
stack_push(p2, atoi(&exp[i]));
}
else if (oper_map(exp[i])){// +- */ (
if (stack_is_empty(p1) || stack_get_top(p1) == '(') {
stack_push(p1, exp[i]);
}
else {
if ( cmp_oper(exp[i], stack_get_top(p1)) < 0) {
stack_push(p1, exp[i]);
}
else {
while (!stack_is_empty(p1) &&
cmp_oper(exp[i],stack_get_top(p1)) >= 0 ) {
stack_push(p2, stack_pop(p1));
}
stack_push(p1, exp[i]);
}
}
}
else if ( exp[i] == ')' ) {
while (!stack_is_empty(p1) && stack_get_top(p1) !='(' ) {
stack_push(p2, stack_pop(p1));
}
stack_pop(p1);//pop (
}
}
stack_push(p2, stack_pop(p1));
int a1, a2, tmp;
exp_len = stack_number(p2);
stack_clean(p1);
for (i = 0; i <= p2->top; i++) {
int tmp = stack_get_pos(p2, i);
if ( oper_map(tmp) ) {
a1 = stack_pop(p1);
a2 = stack_pop(p1);
stack_push(p1, cal(a2, a1, tmp));
}
else {
stack_push(p1, tmp);
}
}
printf("Result:%d\n", stack_pop(p1));
}
root@ubuntu:data-struct#
=======================================