第一步.h文件
typedef struct node {
int data;struct node* prev;
struct node* next;
} Node;
typedef struct stack {
struct node* head;
} Stack;
void stack_init(Stack* stack);
void stack_push(Stack* stack, int data);
int stack_pop(Stack* stack);
int stack_top(Stack* stack);
int stack_isempty(Stack* stack);
第二步.c文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stack.h"
void stack_init(Stack* stack)
{
Node* node = (Node*) malloc(sizeof(Node));
node->data = 0;
node->prev = node;
node->next = node;
stack->head = node;
}
void stack_push(Stack* stack, int data)
{
Node* node = (Node*) malloc(sizeof(Node));
node->data = data;
node->prev = node;
node->next = node;
Node* head = stack->head;
node->next = head->next;
node->prev = head;
node->next->prev = node;
node->prev->next = node;
}
int stack_pop(Stack* stack)
{
if (stack_isempty(stack))
{
printf("debug: stack is empty, pop nothing.\n");
return 0;
}
Node* cur = stack->head->next;
int ret = cur->data;
cur->prev->next = cur->next;
cur->next->prev = cur->prev;
cur->prev = cur;
cur->next = cur;
free(cur);
return ret;
}
int stack_top(Stack* stack)
{
if (stack_isempty(stack))
{
printf("debug: stack is empty, top nothing.\n");
return 0;
}
return stack->head->next->data;
}
int stack_isempty(Stack* stack)
{
if (stack->head->next == stack->head)
return 1;
else
return 0;
}
第三步mian.c文件
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"
enum {
NUM,
OPR
};
int flag = OPR;
void calc_all(Stack* num_stack, Stack* opr_stack);
void calc_once(Stack* num_stack, Stack* opr_stack);
int get_priority(char c)
{
switch (c)
{
case '(':
return 0;
case '+':
case '-':
return 1;
case '*':
case '/':
case '%':
return 2;
case 'n':
return 3;
}
}
void num_handler(Stack* num_stack, char c)
{
// '0'...'9'
int num = 0;
if (flag == NUM)
{
num = stack_pop(num_stack);
num = num*10 + (c-'0');
}
else
num = c - '0';
stack_push(num_stack, num);
flag = NUM;
}
void opr_handler(Stack* num_stack, Stack* opr_stack, char c)
{
int top_opr;
int cur_pri;
int top_pri;
if (c == '-' && flag == OPR)
c = 'n';
while (1)
{
if (stack_isempty(opr_stack))
break;
top_opr = stack_top(opr_stack);
cur_pri = get_priority(c);
top_pri = get_priority(top_opr);
if (cur_pri > top_pri)
break;
else
calc_once(num_stack, opr_stack);
}
stack_push(opr_stack, (int)c);
flag = OPR;
}
void brancket_handler(Stack* num_stack, Stack* opr_stack, char c)
{
if (c == '(')
{
stack_push(opr_stack, (int)c);
flag = OPR;
}
else
{
char c;
while (1)
{
c = (char)stack_top(opr_stack);
if (c != '(')
calc_once(num_stack, opr_stack);
else
{
stack_pop(opr_stack);
break;
}
}
}
}
int calc(Stack* num_stack, Stack* opr_stack, char * str)
{
char * p = str;
for (p = str; *p != '\0'; p++)
{
switch (*p)
{
case '0'...'9':
num_handler(num_stack, *p);
break;
case '+':
case '-':
case '*':
case '/':
case '%':
case 'n':
opr_handler(num_stack, opr_stack, *p);
break;
case '(':
case ')':
brancket_handler(num_stack, opr_stack, *p);
break;
default:
printf("error\n");
}
}
calc_all(num_stack, opr_stack);
int ret = stack_pop(num_stack);
return ret;
}
void calc_once(Stack* num_stack, Stack* opr_stack)
{
char c = (char)stack_pop(opr_stack);
int b;
int a;
b = stack_pop(num_stack);
if (c != 'n')
a = stack_pop(num_stack);
int ret = 0;
switch (c)
{
case '+':
ret = a + b;
stack_push(num_stack, ret);
printf("debug: %d + %d = %d\n", a, b, ret);
break;
case '-':
ret = a - b;
stack_push(num_stack, ret);
printf("debug: %d - %d = %d\n", a, b, ret);
break;
case '*':
ret = a * b;
stack_push(num_stack, ret);
printf("debug: %d * %d = %d\n", a, b, ret);
break;
case '/':
ret = a / b;
stack_push(num_stack, ret);
printf("debug: %d / %d = %d\n", a, b, ret);
break;
case '%':
ret = a % b;
stack_push(num_stack, ret);
printf("debug: %d % %d = %d\n", a, b, ret);
break;
case 'n':
ret = 0 - b;
stack_push(num_stack, ret);
printf("debug: -%d = %d\n", b, ret);
break;
default:
printf("debug: error opr, calc nothing.\n");
}
flag = NUM;
}
void calc_all(Stack* num_stack, Stack* opr_stack)
{
while (1)
{
if (stack_isempty(opr_stack) == 1)
break;
calc_once(num_stack, opr_stack);
}
}
int main()
{
char * str = "(10+-2)*2+123/(2-1)";
// char * str = "10+n2";
Stack* num_stack = (Stack*)malloc(sizeof(Stack));
Stack* opr_stack = (Stack*)malloc(sizeof(Stack));
stack_init(num_stack);
stack_init(opr_stack);
int ret = calc(num_stack, opr_stack, str);
printf("%d\n", ret);
return 0;
}