热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

从约瑟夫问题的递归实现的问题说起

在解决约瑟夫问题时,我比较推荐使用递归,因为递归实现的算法代码更短,逻辑也更清晰,然而很多人有一个疑问,那就是
在解决约瑟夫问题时,我比较推荐使用递归,因为递归实现的算法代码更短,逻辑也更清晰,然而很多人有一个疑问,那就是他们知道递归层数是有极限的,这就意味着当需要很大层数的递归时,递归算法是不可行的,会导致段错误。

        对于这个问题我有三个回答:第一,只要你使用的是计算机而不是你的大脑,你就不要指望什么是无限制的,计算机不是神,计算机里别谈无限。第二,虽然你的c代码是递归实现的,但是编译器生成的二进制文件却不一定会递归调用一个函数,这就涉及了编译器的优化。第三,因为我们使用的大多数是x86体系的冯诺依曼机器,这种机器的编译器一般对于函数调用是通过栈实现的,而我们知道栈的预备空间和最大扩展空间一般都不会太大,然而如果有一种机器,根本就没有栈的概念,或者说即使在x86机器上实现一个变态的编译器,将函数调用退化成简单的jump而不使用栈操作,那么栈的限制将不再存在。

        在基于栈实现函数调用的机器上,我们看一下在什么情况下必须层层嵌套用递归实现。其中一个条件,那就是在递归的过程中,我们无法获知任何计算的中间结果,必须等到最深入一层的函数满足非递归条件而返回时,整个过程才会一层一层的返回,但是如果每一步的中间结果都被保存或者说每一步的递归过程并不是要计算什么值,而仅仅是为了实现一个副作用,那么最终的二进制文件大可不必非要用递归。而且我们知道,递归和迭代是等价的,这一点非常重要。

        编译器不是傻子-其实是实现编译器的人很聪明,编译器一定不会傻到非要用递归生成最终的二进制执行文件,以gcc为例,即使你在c函数中明确使用了递归,在-O3的优化编译选项下,编译器还是会尝试将递归化为迭代的,所生成的二进制objdump文件中你将看不出任何递归调用,这种工作并不是你自己实现的,而是编译器帮你实现的。

        有一种递归被叫做“尾递归”,对于这种递归的理解其实很简单,那就是每一步递归调用的中间结果被保存,因此你可以只使用一个栈帧实现所有的递归过程,因为中间结果随着递归的深入而持续改变,因此你可以将其理解为一种隐含的迭代。对于约瑟夫问题,这种尾递归是很显然的,因为每一步的递归过程的效果其实都是一种副作用,那就是在链表上删除一个节点。但是你还是要告诉编译器这一切,否则编译器仍然使用递归过程生成二进制代码。

        最终的结果,你用-O3选项编译这个c文件,使用objdump查看其目标码,你将看不到任何递归过程,这就突破了栈的限制,但是记住,限制仍然是有的,因为很抱歉,你用的是计算机这种奴隶式的工具,计算机说的最多的话,那就是:Sorry, it is beyond my ablity!






推荐阅读
  • 兆芯X86 CPU架构的演进与现状(国产CPU系列)
    本文详细介绍了兆芯X86 CPU架构的发展历程,从公司成立背景到关键技术授权,再到具体芯片架构的演进,全面解析了兆芯在国产CPU领域的贡献与挑战。 ... [详细]
  • C语言是计算机科学和编程领域的基石,许多初学者在学习过程中会感到困惑。本文将详细介绍C语言的基本概念、关键语法和实用示例,帮助你快速上手C语言。 ... [详细]
  • centos 7.0 lnmp成功安装过程(很乱)
    下载nginx[rootlocalhostsrc]#wgethttp:nginx.orgdownloadnginx-1.7.9.tar.gz--2015-01-2412:55:2 ... [详细]
  • 本文详细介绍如何使用Netzob工具逆向未知通信协议,涵盖从基本安装到高级模糊测试的全过程。通过实例演示,帮助读者掌握Netzob的核心功能。 ... [详细]
  • PHP函数的工作原理与性能分析
    在编程语言中,函数是最基本的组成单元。本文将探讨PHP函数的特点、调用机制以及性能表现,并通过实际测试给出优化建议。 ... [详细]
  • 开发笔记:前端之前端初识
    开发笔记:前端之前端初识 ... [详细]
  • JSP(JavaServer Pages)和Servlet都是Java Web开发中的重要技术。JSP可以看作是Servlet的扩展,主要关注页面的展示效果。而Servlet则更侧重于处理业务逻辑。本文将详细介绍它们的相同点和不同点。 ... [详细]
  • 高效重装Windows 10系统指南
    如何快速地为您的电脑重装Windows 10系统?本文将详细介绍从下载系统镜像到安装完成的每一步操作。 ... [详细]
  • 本文介绍了 Go 语言中的高性能、可扩展、轻量级 Web 框架 Echo。Echo 框架简单易用,仅需几行代码即可启动一个高性能 HTTP 服务。 ... [详细]
  • 如何修改360极速浏览器的默认安装路径
    本文介绍了一种有效的方法,帮助用户在新版360极速浏览器中成功更改默认安装路径,解决因权限问题导致的安装失败。 ... [详细]
  • 高端存储技术演进与趋势
    本文探讨了高端存储技术的发展趋势,包括松耦合架构、虚拟化、高性能、高安全性和智能化等方面。同时,分析了全闪存阵列和中端存储集群对高端存储市场的冲击,以及高端存储在不同应用场景中的发展趋势。 ... [详细]
  • 在 CentOS 6.4 上安装 QT5 并启动 Qt Creator 时,可能会遇到缺少 GLIBCXX_3.4.15 的问题。这是由于系统中的 libstdc++.so.6 版本过低。本文将详细介绍如何通过更新 GCC 版本来解决这一问题。 ... [详细]
  • Linux CentOS 7 安装PostgreSQL 9.5.17 (源码编译)
    近日需要将PostgreSQL数据库从Windows中迁移到Linux中,LinuxCentOS7安装PostgreSQL9.5.17安装过程特此记录。安装环境&#x ... [详细]
  • 为了在Hadoop 2.7.2中实现对Snappy压缩和解压功能的原生支持,本文详细介绍了如何重新编译Hadoop源代码,并优化其Native编译过程。通过这一优化,可以显著提升数据处理的效率和性能。此外,还探讨了编译过程中可能遇到的问题及其解决方案,为用户提供了一套完整的操作指南。 ... [详细]
  • MATLAB字典学习工具箱SPAMS:稀疏与字典学习的详细介绍、配置及应用实例
    SPAMS(Sparse Modeling Software)是一个强大的开源优化工具箱,专为解决多种稀疏估计问题而设计。该工具箱基于MATLAB,提供了丰富的算法和函数,适用于字典学习、信号处理和机器学习等领域。本文将详细介绍SPAMS的配置方法、核心功能及其在实际应用中的典型案例,帮助用户更好地理解和使用这一工具箱。 ... [详细]
author-avatar
BBCong
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有