递归的作用之一就是用来解决递归形式的问题。我们来分析一个用递归形式描述的问题,并用递归来解决这个问题。
1、问题描述
例题: 四则运算表达式求值
输入为四则运算表达式,仅由整数、+、-、*、/ 、(、)组成,没有空格,要求求其值。假设运算符结果都是整数。"/"结果也是整数。
样例输入:(2+3)*(5+7)+9/3
样例输出: 63
2、问题分析
表达式可以看成是由一个或者多个项相加减,项可以看成由多个因子乘除,一个因子可以是一个整数,也可以是左括号+表达式+右括号。这里出现的循环,表达式的定义是个递归形式的定义。
表达式,项,因子三者之间的定义表示如下:
表达式定义中,从左侧箭头进入,右侧箭头出来,便构成一个表达式,可以看出,表达式可以由一个或者多个项相加减组成;项的定义中,项是由一个或者多个因子相乘除组成;因子可以是一个整数,也可以是左括号+表达式+右括号。因此对于表达式求值的问题可以用递归来解决。
#include <iostream>
using namespace std;
int expression_value(); //求表达式的值
int term_value(); //求项的值
int factor_value(); //求因子的值
int main()
{
cout << expression_value() << endl;
return 0;
}
//求一个表达式的值
//先求出第一项的值,判断后面有没有项了,有,继续相加减,没有了,输出结果。
//通过判断项后面的加减号来决定是加还是减
int expression_value()
{
int result = term_value(); //求第一项的值
bool more = true;
while (more)
{
char op = cin.peek(); //查看一个字符,不取走
if (op == '+' || op == '-')
{
cin.get(); //取走一个字符
if (op == '+')
result = result + term_value();
else
result = result - term_value();
}
else
more = false;
}
return result;
}
//求一个项的值
//先求出第一个因子的值,判断后面有没有因子了,有,相乘除,没有,输出结果
//通过判断因子后面的乘除号决定是乘,还是除
int term_value()
{
int result = factor_value(); //求第一个因子的值
while (true)
{
char op = cin.peek(); //查看一个字符,不取走
if (op == '*' || op == '/')
{
cin.get(); //取走一个字符
if (op == '*')
result = result*factor_value();
else
result = result / factor_value();
}
else
break;
}
return result;
}
//求一个因子的值
//取第一个字符,判断是一个整数,还是左括号+表达式+右括号
//如果是表达式,求出表达式的值,如果是整数,将字符串转化为int
int factor_value()
{
int result = 0;
char op = cin.peek();
if (op == '(') //因子是左括号+表达式+右括号
{
cin.get();
result = result + expression_value();
cin.get();
}
else //因子是一个整数
{
while (isdigit(op))
{
result = result * 10 + op - '0';
cin.get();
op = cin.peek();
}
}
return result;
}
对代码中使用的三个函数cin.peek(),cin.get(),isdigit()说明如下:
cin.peek();
函数说明:从输入流中读取一个字符,但该字符并未从输入流中删除
返回值:读入的字符
cin.get();
用法1: cin.get(字符变量名),用来接收字符
char ch;
ch=cin.get();或者cin.get(ch);
用法2:cin.get(字符数组名,接收字符数目),用来接收一行字符串,可以接收空格
char a[20];
cin.get(a,20);
用法3:cin.get(无参数),用于舍弃输入流中的不需要的字符,或者舍弃回车
int isdigit(int c);
函数说明:检查参数是否为十进制数字字符
返回值:若参数c为阿拉伯数字0~9,则返回非0值,否则返回0。
3、总结
学会分析递归形式的问题