一、栈的简单应用
1、数制转换。
2、括号匹配。
3、逆波兰表达式的计算。
二、代码
void HexTran(DataType x,DataType k) //任意进制转换
{
DataType result = 0;
Stack s;
DataType i;
StackInit(&s);
while (x)
{
i = x%k; //取余
x = x/k;
StackPush(&s,i); //把转换结果入栈
}
while (StackEmpty(&s))
{
DataType top = StackTop(&s);
printf("%d ",top);
StackPop(&s);
}
}
DataType BracketsMatch(char *p) //括号匹配
{
Stack s;
StackInit(&s);
assert(p);
while (*p) //循环检测每一个符号
{
if (*p == '(')
{
StackPush(&s,'('); //正括号入栈
}
if (*p==')')
{
if (0 == StackEmpty(&s)) //反括号且栈为空则不匹配
{
return 0;
}
StackPop(&s); //反括号且栈不为空则匹配
}
p++;
}
if (0 == StackEmpty(&s)) //栈为空则匹配
{
return 1; //匹配
}
return 0; //不匹配
}
int RPNExpression(Cell *rpn,size_t n) //逆波兰表达式
{
Stack s;
size_t i = 0;
assert(rpn);
StackInit(&s);
while (i<n)
{
if (rpn[i].type == NUM) //数值入栈
{
StackPush(&s,rpn[i].num);
i++;
}
else //遇到计算符号就取出栈顶值计算
{
DataType right = StackTop(&s);
DataType left;
StackPop(&s);
left = StackTop(&s);
StackPop(&s);
switch (rpn[i].num)
{
case ADD: StackPush(&s,left + right);
break;
case SUB: StackPush(&s,left - right);
break;
case MUL: StackPush(&s,left * right);
break;
case DIV: StackPush(&s,left / right);
break;
default:
break;
}
i++;
}
}
return StackTop(&s);
}
三、整体代码和测试结果:
1、StackApply.h
typedef enum RPN_TYPE //后缀表达式的状态
{
NUM,
SYMBOL,
ADD,
SUB,
MUL,
DIV
}RPN_TYPE;
typedef struct Cell //结构
{
RPN_TYPE type;
int num;
}Cell;
void HexTran(DataType x,DataType k); //任意进制转换
DataType BracketsMatch(char *p); //括号匹配
int RPNExpression(Cell *rpn,size_t n); //逆波兰表达式
2、StackApply.c
void HexTran(DataType x,DataType k) //任意进制转换
{
DataType result = 0;
Stack s;
DataType i;
StackInit(&s);
while (x)
{
i = x%k; //取余
x = x/k;
StackPush(&s,i); //把转换结果入栈
}
while (StackEmpty(&s))
{
DataType top = StackTop(&s);
printf("%d ",top);
StackPop(&s);
}
}
DataType BracketsMatch(char *p) //括号匹配
{
Stack s;
StackInit(&s);
assert(p);
while (*p) //循环检测每一个符号
{
if (*p == '(')
{
StackPush(&s,'('); //正括号入栈
}
if (*p==')')
{
if (0 == StackEmpty(&s)) //反括号且栈为空则不匹配
{
return 0;
}
StackPop(&s); //反括号且栈不为空则匹配
}
p++;
}
if (0 == StackEmpty(&s)) //栈为空则匹配
{
return 1; //匹配
}
return 0; //不匹配
}
int RPNExpression(Cell *rpn,size_t n) //逆波兰表达式
{
Stack s;
size_t i = 0;
assert(rpn);
StackInit(&s);
while (i<n)
{
if (rpn[i].type == NUM) //数值入栈
{
StackPush(&s,rpn[i].num);
i++;
}
else //遇到计算符号就取出栈顶值计算
{
DataType right = StackTop(&s);
DataType left;
StackPop(&s);
left = StackTop(&s);
StackPop(&s);
switch (rpn[i].num)
{
case ADD: StackPush(&s,left + right);
break;
case SUB: StackPush(&s,left - right);
break;
case MUL: StackPush(&s,left * right);
break;
case DIV: StackPush(&s,left / right);
break;
default:
break;
}
i++;
}
}
return StackTop(&s);
}
3、test.c
void Test5()
{
HexTran(1347,8); //数制转换
printf("%d\n",BracketsMatch("(a*(b+c)-d)")); //括号匹配问题
Cell rpn[] =
{
{NUM, 12},
{NUM, 3},
{NUM, 4},
{SYMBOL, ADD},
{SYMBOL, MUL},
{NUM, 6},
{SYMBOL, SUB},
{NUM, 8},
{NUM, 2},
{SYMBOL, DIV},
{SYMBOL, ADD},
};
printf("%d \n",RPNExpression(rpn,sizeof(rpn)/sizeof(Cell))); //逆波兰表达式
}
应用中涉及到栈的操作请看此文章
四、运行结果