递归算法实例应用(二)

简介: 递归算法实例应用(二):Polish Expression问题

Polish Expression

Description

A Polish expression is an arithmetic expression that prepositions an operator. For example, the Polish representation of the ordinary expression 2 + 3 is + 2 3. The advantage of Polish expressions is that there is no need for precedence between operators, nor for parentheses to change the order of operations. For example, the Polish representation of (2 + 3) * 4 is * + 2 3 4. This problem evaluates the value of the Polish expression, where the operators include ‘+’,‘-’,‘*’,‘/’.

Input

The input is a line with Spaces separating both the operator and the operand, which is a floating-point number.

Output

The output is a line, the value of the expression.

Sample Input

* + 11.0 12.0 + 24.0 35.0

Sample Output

1357.000000

关于前缀表达式,又称波兰表达式,它是一种不需要括号的计算表达式的表示法。它将操作符号写在操作数之前,即二元运算符总是置于与之相关的两个运算对象之前,而每一个对象也可以是一个波兰表达式,因此波兰式是一个明显的以递归形式定义的问题。所以我们可以采用递归的方式进行解决。

同时,在数据结构栈相关章节,也有更为详细的阐述,主要是通过栈的方法将我们所熟知的中缀表达式转为后缀表达式(逆波兰表达式)或前缀表达式(波兰表达式),因为在计算机中通过前缀、后缀表达式相比于中缀表达式有着更广、更深的用途,只需入栈和出栈就可以搞定任何普通中缀表达式的运算。简言之为:如果当前字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。具体通过栈来模拟算法转换在此不加阐述,本文属递归篇,所以通过递归形式来解决问题。


算法思想:

当仅通过递归来实现时,相比于栈操作问题会变得更加简单。

所以,我们从波兰式的定义出发:

  1. 一个数是一个波兰表达式,值为数本身。
  2. “运算符” “波兰表达式1” “波兰表达式2” 是一个波兰表达式,值为波兰表达式1 运算符 波兰表达式2的值。

发现该定义本身是一个以递归形式来定义的,如2中,在定义波兰式时又用到了波兰式的概念,所以波兰式是一个以递归形式定义的问题。

而在1中,该条定义是明确的一条定义,并没有递归的定义形式出现。

波兰式的递归形式之所以成立,是因为1中这条非递归形式的定义在约束,作为递归的终止条件。也就是说,因为1中定义的存在使得2中的定义不存在无限循环定义的形式,使得波兰式的递归形式成立。

当对于波兰式的递归定义形式清楚以后问题就迎刃而解。

由于C/C++语言具有输入/输出缓冲区的特性,所以可以在程序等待输入时一次性将待输入字符串输入完整。


代码逻辑:

  1. 依次读入每一个字符串
  2. 判断字符串类型:

    • 若该字符串为‘+’,则后两个字符串应该为波兰式1和波兰式2,并对两波兰式做加法运算,其值作为返回值。
    • 若该字符串为‘-’,则后两个字符串应该为波兰式1和波兰式2,并对两波兰式做减法运算,其值作为返回值。
    • 若该字符串为‘*’,则后两个字符串应该为波兰式1和波兰式2,并对两波兰式做乘法运算,其值作为返回值。
    • 若该字符串为‘/’,则后两个字符串应该为波兰式1和波兰式2,并对两波兰式做除法运算,其值作为返回值。
    • 若该字符串为数字,则根据定义1可知,改波兰式的值为该值本身,所以返回该字符串对应的双浮点数类型即可,可通过stdlib.h头文件中atof()函数进行转换。
  3. 输出波兰式的值

代码整合:

double PolishExp() {
    char str[20];
    scanf("%s", str);
    switch (str[0]) {
        case '+':
            return PolishExp() + PolishExp(); // +ab -> a+b
        case '-':
            return PolishExp() - PolishExp(); // -ab -> a-b
        case '*':
            return PolishExp() * PolishExp(); // *ab -> a*b
        case '/':
            return PolishExp() / PolishExp(); // /ab -> a/b
        default:
            return atof(str); //将字符串转为双浮点数类型
    }
}

By Ss1Two 2023/01/14

目录
相关文章
|
3天前
|
机器学习/深度学习 数据采集 自然语言处理
理解并应用机器学习算法:神经网络深度解析
【5月更文挑战第15天】本文深入解析了神经网络的基本原理和关键组成,包括神经元、层、权重、偏置及损失函数。介绍了神经网络在图像识别、NLP等领域的应用,并涵盖了从数据预处理、选择网络结构到训练与评估的实践流程。理解并掌握这些知识,有助于更好地运用神经网络解决实际问题。随着技术发展,神经网络未来潜力无限。
|
3天前
|
算法 Python
利用贝叶斯算法对简单应用实现预测分类
利用贝叶斯算法对简单应用实现预测分类
6 0
|
3天前
|
机器学习/深度学习 算法 API
【Paddle】PCA线性代数基础 + 领域应用:人脸识别算法(1.1w字超详细:附公式、代码)
【Paddle】PCA线性代数基础 + 领域应用:人脸识别算法(1.1w字超详细:附公式、代码)
8 0
|
3天前
|
机器学习/深度学习 数据采集 算法
深入理解并应用机器学习算法:支持向量机(SVM)
【5月更文挑战第13天】支持向量机(SVM)是监督学习中的强分类算法,用于文本分类、图像识别等领域。它寻找超平面最大化间隔,支持向量是离超平面最近的样本点。SVM通过核函数处理非线性数据,软间隔和正则化避免过拟合。应用步骤包括数据预处理、选择核函数、训练模型、评估性能及应用预测。优点是高效、鲁棒和泛化能力强,但对参数敏感、不适合大规模数据集且对缺失数据敏感。理解SVM原理有助于优化实际问题的解决方案。
|
3天前
|
机器学习/深度学习 算法
理解并应用机器学习算法:决策树
【5月更文挑战第12天】决策树是直观的分类与回归机器学习算法,通过树状结构模拟决策过程。每个内部节点代表特征属性,分支代表属性取值,叶子节点代表类别。构建过程包括特征选择(如信息增益、基尼指数等)、决策树生成和剪枝(预剪枝和后剪枝)以防止过拟合。广泛应用在信贷风险评估、医疗诊断等领域。理解并掌握决策树有助于解决实际问题。
|
3天前
|
机器学习/深度学习 算法
应用规则学习算法识别有毒的蘑菇
应用规则学习算法识别有毒的蘑菇
|
3天前
|
存储 机器学习/深度学习 算法
R语言贝叶斯Metropolis-Hastings采样 MCMC算法理解和应用可视化案例
R语言贝叶斯Metropolis-Hastings采样 MCMC算法理解和应用可视化案例
|
3天前
|
数据采集 机器学习/深度学习 算法
数据分享|WEKA关联规则挖掘Apriori算法在学生就业数据中的应用
数据分享|WEKA关联规则挖掘Apriori算法在学生就业数据中的应用
|
3天前
|
机器学习/深度学习 自然语言处理 算法
机器学习算法原理与应用:深入探索与实战
【5月更文挑战第2天】本文深入探讨机器学习算法原理,包括监督学习(如线性回归、SVM、神经网络)、非监督学习(聚类、PCA)和强化学习。通过案例展示了机器学习在图像识别(CNN)、自然语言处理(RNN/LSTM)和推荐系统(协同过滤)的应用。随着技术发展,机器学习正广泛影响各领域,但也带来隐私和算法偏见问题,需关注解决。
|
3天前
|
机器学习/深度学习 算法 C语言
【C言专栏】递归算法在 C 语言中的应用
【4月更文挑战第30天】本文介绍了递归算法在C语言中的应用,包括基本概念(通过调用自身解决子问题)、特点(调用自身、终止条件、栈空间)和实现步骤(定义递归函数、分解问题、设置终止条件、组合解)。文中通过阶乘计算和斐波那契数列两个案例展示了递归的使用,强调了递归可能导致的栈溢出问题及优化需求。学习递归有助于理解和应用“分而治之”策略。