第二章的题目没有太多可以记的,其中第二题让验证所有花括号都正确成对出现让我想起“表达式计算器”,现实现如下:
#include <stdio.h>
//存储操作符
struct OpeStack
{
int iTop;
char acStack[100];
};
//存储数字
struct NumStack
{
int iTop;
int aiStack[100];
};
//是数字
static int isNumber(char ch)
{
return (ch <= '9' && ch >= '0') ? ch - '0' : -1;
}
//是运算符
static int isOperator(char ch)
{
return (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')' );
}
//返回运算符优先级
static int OpePriority(char ch)
{
switch(ch)
{
case '+':
case '-':
{
return 1;
}
case '*':
case '/':
{
return 2;
}
case '(':
{
return 3;
}
default:
return -1;
}
}
//根据输入运算符和数做运算,a是运算符左边的数,b是运算符右边的数
static int CalPart(int a, char Operator, int b)
{
switch(Operator)
{
case '+':
{
return a + b;
}
case '-':
{
return a - b;
}
case '*':
{
return a * b;
}
case '/':
{
return a / b;
}
default:
return ~0;
}
}
//对输入表达式进行计算,并将结果保存在iResult中
static int Calculate(const char *acExpression, int *iResult)
{
int i;
int tmpNum;
int iNum;
//两个栈一个用来放运算符,一个用来放数字
struct OpeStack tOperator;
struct NumStack tNumber;
tOperator.iTop = 0;
tNumber.iTop = 0;
for(i = 0; acExpression[i] != '\0'; i++)
{
iNum = 0;
//如果是数字的话处理数字
if(isNumber(acExpression[i]) != -1)
{
int j = i;
while((tmpNum = isNumber(acExpression[j])) != -1)
{
iNum = iNum *10 + tmpNum;
j++;
}
tNumber.aiStack[++tNumber.iTop] = iNum;
}
//如果是运算符的话
else if(isOperator(acExpression[i]) == 1)
{
//如果遇到右括号就计算直到左括号为止
if(acExpression[i] == ')')
{
while(tOperator.acStack[tOperator.iTop] != '(')
{
if(tOperator.iTop < 1)
{
printf("bracket is not match\n");
return -1;
}
int a = tNumber.aiStack[tNumber.iTop--];
int b = tNumber.aiStack[tNumber.iTop--];
int iResult = CalPart(b, tOperator.acStack[tOperator.iTop--], a);
tNumber.aiStack[++tNumber.iTop] = iResult;
}
tOperator.iTop--;
}
//如果是第一个符号或者是括号后的第一符号,直接入栈
else if(tOperator.iTop == 0 || tOperator.acStack[tOperator.iTop] == '(')
{
tOperator.acStack[++tOperator.iTop] = acExpression[i];
}
else
{
//如果当前优先级低或相等,就先计算栈顶的符号
//如果优先级高就入栈
if(OpePriority(acExpression[i]) <= OpePriority(tOperator.acStack[tOperator.iTop]))
{
int a = tNumber.aiStack[tNumber.iTop--];
int b = tNumber.aiStack[tNumber.iTop--];
char cOpr = tOperator.acStack[tOperator.iTop--];
int iResult = CalPart(b, cOpr, a);
tNumber.aiStack[++tNumber.iTop] = iResult;
tOperator.acStack[++tOperator.iTop] = acExpression[i];
}
else
{
tOperator.acStack[++tOperator.iTop] = acExpression[i];
}
}
}
else
{
return -1;
}
}
//表达式读完后开始计算
while(tOperator.iTop >= 1)
{
int a = tNumber.aiStack[tNumber.iTop--];
int b = tNumber.aiStack[tNumber.iTop--];
int iResult = CalPart(b, tOperator.acStack[tOperator.iTop--], a);
tNumber.aiStack[++tNumber.iTop] = iResult;
}
//如果数字栈中最后只剩一个元素,说明计算正确;否则计算错误
if(tNumber.iTop == 1)
{
*iResult = tNumber.aiStack[1];
}
else
{
return -2;
}
return 0;
}
int main(void)
{
char acExprestion[100] = "2*4/(1+3)+4";
int iRes;
int ret = Calculate(acExprestion, &iRes);
if(!ret)
printf("result:%d\n", iRes);
return 0;
}
总体思路是用栈来将中缀表达式转换为后缀表达式,注释的还是很清楚的。