一个看起来是O(n)的function但实际上是O(n^2)

哈喽大家好,今天看到了一个有趣的程序码片段(来源),这个function的功能就是把一个字串转为全小写,看起来没什麽特别的,写起来也相当直观:

/* 这段程序码有问题 */
void lower(char *s)
{
    size_t i;
    for (i = 0; i < strlen(s); i++)
        if (s[i] >= 'A' && s[i] <= 'Z')
            s[i] -= ('A' - 'a');
}

他看起来就是一个O(n)的function,但实际上却是O(n^2),这是因为在for回圈的每一次开头,都会重新呼叫strlen(s),而strlen(s)本身又是一个O(n)的function所以整个for回圈的复杂度就是O(n^2)

为什麽compiler不帮我们自动优化,让strlen(s)算一次就好?
虽然我们人类可以判断出for回圈的每一次递回,strlen(s)的回传值都是不会改变的,但是对於compiler来说这却是一个困难的任务,主要原因在於for回圈的内容牵扯到字串内容的改变,要compiler判断字串是否维持原本的长度太困难了

解决方法:

void lower(char *s)
{
    size_t i;
    size_t len = strlen(s);
    for (i = 0; i < len; i++)
        if (s[i] >= 'A' && s[i] <= 'Z')
            s[i] -= ('A' - 'a');
}

经由人类的判断,把字串长度的计算放到回圈外面


<<:  Day11 职训(机器学习与资料分析工程师培训班): Python程序设计, 建立Model+载入

>>:  python的基本语法-1

DAY30 第一次参与铁人赛的心得

这是我们第一次参加铁人赛,很高兴能参加这个IT铁人赛,而且我们有完赛,或许内容没有很完善,可能还有错...

Day 2 - 谈谈伦理骇客

出於书本 Chapter 1. Introduction to Ethical Hacking 骇客...

【Day11】忙得团团转的回圈

回圈指的是「重复做某件事,次数随着数值『递增」或『递减』,当数值满足所设的条件,则退出回圈」。 所...

Day 06. 安装 Zabbix Agent 在 Ubuntu

今天要跟大家介绍如何在其他机器上安装Zabbix Agent 进行监控~ 这次选用的 OS 是Ubu...

电源供应

电源是一种向电力负载提供电力的电气设备。电源的主要功能是将电流从源头转换成正确的电压、电流和频率,为...