递归与尾递归

最近学习算法遇到一个很有意思的事情。
就是大家都知道递归用的不好是非常占内存而且耗时的。原因是因为递归函数是一层一层调用函数的。而在计算机中函数调用是通过栈(stack)这种数据结构实现,每当调用一层函数,栈就会加一层栈帧,每当函数返回,栈就会减少一层栈帧。所以递归用的不好可能会导致栈溢出。或者运行时间特别长。

优化递归的方法可以使用尾递归,事实上时间复杂度一样。尾递归主要是对栈内存空间优化,其实是由于对空间优化导致内存分配的工作减少产生。
而且可以把循环看成一种特殊的尾递归。
尾递归:在函数返回时只调用自身。尾递归在执行过程中不需要回溯。因为尾递归把结果包含在一部分参数中。故每次调用实际上都是对参数的一个更新过程。

//普通递归
    public static long fib_1(int n){
        if(n<=1){
            return 1;
        }
        return fib_1(n-1)+fib_1(n-2);
    }

    //尾递归
    public static long fib_2(int n){
        return fib_iter(1,1,n);
    }

    public static long fib_iter(long a,long b,int n){
        if(n<=0){
            return a;
        }
        return fib_iter(b,a+b,n-1);
    }

    //for循环
    public static long fib_3(int n){
        if(n<=1){
            return 1;
        }else{
            long fib=0;
            long a=1;
            long b=1;
            for(int i=1;i<n;i++){
                fib=a+b;
                a=b;
                b=fib;
            }
            return fib;
        }
    }


 //测试
    public static void main(String[] args) {
        int  NUM=40;
        long startTime1=System.currentTimeMillis();
        long m=fib_2(NUM);
        long endTime1=System.currentTimeMillis();
        System.out.println("fib_2:"+m);
        System.out.println("Time:"+(endTime1-startTime1));

        long startTime2=System.currentTimeMillis();
        long k=fib_3(NUM);
        long endTime2=System.currentTimeMillis();
        System.out.println("fib_3:"+k);
        System.out.println("Time:"+(endTime2-startTime2));

        long startTime=System.currentTimeMillis();
        long n=fib_1(NUM);
        long endTime=System.currentTimeMillis();
        System.out.println("fib_1:"+n);
        System.out.println("Time:"+(endTime-startTime));
    }

输出:
fib_2:165580141
Time:0
fib_3:165580141
Time:0
fib_1:165580141
Time:1556
可以看到for循环和尾递归还是非常快的。

03-08
### MathPix工具介绍 Mathpix Snipping Tool 是一款强大的数学公式识别工具,从最初的原型发展至今已经历了多次迭代和功能增强[^1]。该工具不仅能处理简单的数学表达式,还可以应对复杂的数学模型以及多行公式,并且支持手写公式的识别。 这款应用程序通过不断的科技创新与用户反馈改进,在学术研究和技术领域赢得了良好声誉,成为许多科研人员不可或缺的工作伙伴之一。除了基本的功能外,Mathpix 还提供了多种高级特性来满足不同用户的特定需求。 ### 使用方法 #### 安装与启动 为了使用 Mathpix Snipping Tool ,首先需要下载安装程序并按照提示完成设置过程。一旦成功安装后即可随时调用此应用来进行截图操作。 #### 截取屏幕上的公式图像 当遇到想要转换成 LaTeX 或 AsciiMath 的图片时,只需打开软件界面按下快捷键(默认为 `Ctrl+Alt+M`),此时鼠标指针会变为十字形状以便于选取目标区域;框选所需部分之后松开按键即刻上传至云端服务器等待进一步分析处理。 #### 获取LaTeX代码片段 经过短暂几秒钟的时间延迟过后,所截获的内容将以纯文本形式显示出来供复制粘贴到其他编辑器当中继续编写文档或是分享给他人查看交流之用。 ```python import pyperclip # 假设已获取到LaTeX字符串 stored_in_variable named latex_code pyperclip.copy(latex_code) print("LaTeX code has been copied to clipboard.") ``` 对于希望深入探索更多可能性的用户来说,可以考虑查阅官方提供的扩展插件——如用于解析Markdown文件内的公式标记语法的库 **mathpix-markdown-it** [^2] ——这将进一步提升工作效率和个人体验感。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值