❤️学姐说她用 8 行代码写了 8 个算法(上)❤️(推荐收藏)

Posted 英雄哪里出来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了❤️学姐说她用 8 行代码写了 8 个算法(上)❤️(推荐收藏)相关的知识,希望对你有一定的参考价值。

一、前言

  本文适合对算法处于朦胧期的初学者,文字浅显易懂,并且配有生动有趣的动图,也是作者呕心沥血之作,希望对刚入大学,或者职场上想要涉足算法的青年同僚有所启示。
  学习算法,任何时候都不嫌晚,大不了就是大器晚成而已,所以无论你是30岁,40岁,50岁,甚至60岁,只要下了决心,就已经成功了一半!本文的故事发生在 ❤️学姐教你 10 道题搞定 c 语言❤️ 的两年后,剧情扑朔迷离,作者至今回忆起来还历历在目。

二、朝思暮想

  • 自从上次一别,不知何时才能相见,不免有些感伤。于是,那天晚上,我,辗转反侧,彻夜难眠,寝不安席,食无甘味。
    在这里插入图片描述
    不太聪明的亚子
  • 从来没有一个女孩子可以让我如此朝思暮想,魂牵梦萦。
  • 可能是因为她还没有把她的毕生算法教会给我,怎么一声不吭就人间蒸发了呢!我不甘心!
  • 就算是天涯海角,我也要找到你!
    在这里插入图片描述
  • 终于,在一个夜黑风高的晚上,让我在睡梦中见到了她,梦里的她比现实中还要逗比。竟然给我写下了八行代码!
    在这里插入图片描述
  • 也就是因为那个晚上,成就了我后来的 ❤️《夜深人静写算法》❤️
  • 她告诉我,一行代码代表一个算法!我觉得她在侮辱我的智商!
  • 那天晚上大致是这样的 … …

三、南柯一梦


在这里插入图片描述

四、梦中的梦中

  • 哎,越想越不对劲!
  • 所以我打算继续睡,看看能不能继续梦到学姐。
  • 果然……功夫不负有心人……
  • 学姐出现了!!!

  • 学姐还是像往常一样,心思缜密,替人着想,越来越崇拜她了。

在这里插入图片描述

五、梦中人的梦中

算法一

在这里插入图片描述

【例题1】给定 n ( n ≤ 65535 ) n(n \\le 65535) n(n65535),求 ∑ i = 1 n i = 1 + 2 + . . . + n \\sum_{i=1}^n i = 1 + 2 + ... + n i=1ni=1+2+...+n

  • 这是一个等差数列!
  • 我直接用等差数列的求和公式就行了。
int sum(int n) {
    return n * (n + 1) / 2;
}

在这里插入图片描述

  • 然后我调试了一下,发现:
    在这里插入图片描述
  • n = 65535 n=65535 n=65535 时,输出的竟然是负数!

原因是因为 n ∗ ( n + 1 ) = 65535 ∗ 65536 = ( 2 16 − 1 ) 2 16 = 2 32 − 2 16 n * (n + 1) = 65535 * 65536 = (2^{16}-1)2^{16} = 2^{32} -2^{16} n(n+1)=6553565536=(2161)216=232216,而 i n t int int 能够表示的最大值为 2 31 − 1 2^{31}-1 2311,所以产生了溢出。就变成了负数。至于为什么溢出会变成负数,可以了解补码相关的知识:c++ 补码详解

  • 这里只需要对 n n n 进行奇偶性判定,将除法放在乘法之前,就可以防止溢出了。即:
  • s u m ( n ) = { ( n + 1 ) / 2 × n n 为 奇 数 n / 2 × ( n + 1 ) n 为 偶 数 sum(n) = \\begin{cases} (n+1)/2 \\times n & n 为奇数 \\\\ n/2 \\times (n+1) & n 为偶数 \\end{cases} sum(n)={(n+1)/2×nn/2×(n+1)nn
  • c++ 实现如下:
int sum(int n) {
    if(n % 2 == 1) {
        return (n + 1) / 2 * n;
    }else {
        return n / 2 * (n + 1);
    }
}
  • 然后我们再通过三目运算符写成一行代码,如下:
int sum(int n) {
    return (n%2) ? (n+1)/2*n : n/2*(n+1);
}

这里的 condition ? a : b是 c/c++ 中的三目运算符,含义是根据表达式condition的值的真或假,选择返回 a还是 b。由于对于一个数 x x x x x x 非0就是真,为0就是假,所以可以直接省略 x == 0的判断。

在这里插入图片描述

  • 通过这段代码,我了解了 32位整数的溢出、补码表示、三目运算符、表达式真值的省略写法。

算法二

在这里插入图片描述

【例题2】给定 n ( n < 16 ) n(n \\lt 16) n(n<16),求 ∏ i = 1 n i = 1 × 2 × . . . × n \\prod_{i=1}^n i = 1 \\times 2 \\times ... \\times n i=1ni=1×2×...×n

  • 由于 n n n 比较小,所以我打算直接暴力枚举,大概可以写成这样:
int sum(int n) {
    int s = 1;
    for(int i = 1; i <= n; ++i) {
        s *= i;
    }
    return s;
}
  • 但是学姐说的一行代码好像比较难办到,我继续压缩,把 s这个变量放到循环体内和i一起初始化,并且把乘法和循环放到同一行,变成了下面这副样子。
int sum(int n) {
    for(int s = 1, i = 1; i <= n; ++i) s *= i;
    return s;
}
  • 这时候发现编译不过!!!
    在这里插入图片描述
  • 原因是:s的作用域在循环体内,所以无法在循环体外部进行使用,但是我们这个函数有需要有一个返回值,总不能把函数体给返回吧?这可如何是好!

在这里插入图片描述

  • 由于那时候,我对递归还没有什么概念,所以一脸懵逼。

在这里插入图片描述

  • 我还是听不懂……

  • 这下我就懂了!
  • 我们可以定义这么一个函数 f ( x ) = 1 × 2 × 3 × . . . × x f(x) = 1 \\times 2 \\times 3 \\times ... \\times x f(x)=1×2×3×...×x,其中 x ≥ 0 x \\ge 0 x0
  • x > 0 x > 0 x>0 时,代入 ( x − 1 ) (x-1) (x1),显然有 f ( x − 1 ) = 1 × 2 × 3 × . . . × ( x − 1 ) f(x-1) = 1 \\times 2 \\times 3 \\times ... \\times (x-1) f(x1)=1×2×3×...×(x1)
  • 于是,可以得到:
  • f ( x ) f ( x − 1 ) = x \\frac {f(x)} {f(x-1)} = x f(x1)f(x)=x
  • 由于 f ( x − 1 ) > 0 f(x-1) > 0 f(x1)>0, 等式两边可以同时乘上 f ( x − 1 ) f(x-1) f(x1),很容易得出递推公式如下:
  • f ( x ) = { 1 ( x = 0 ) f ( x − 1 ) × x ( x > 0 ) f(x) = \\begin{cases} 1 & (x = 0) \\\\ f(x-1) \\times x & (x > 0)\\end{cases} f(x)={1f(x1)×x(x=0)(x>0)
  • 所以,翻译成 c/c++ 的语言,就可以写成这样:
int f(int x) {
    if(x == 0) {
        return 1;
    }else {
        return f(x-1) * x;
    }
}
  • 然后利用三目运算符,改成一行代码,得到:
int f(int x) {
    return x ? f(x-1) * x : 1;
}

在这里插入图片描述

  • 通过这段代码,我了解了 递推公式 和 递归调用。

算法三


【例题3】现在有一个 n ( n ≤ 10000 ) n(n \\le 10000) n(n10000) 个元素的数组 a [ i ] a[i] a[i],但是我们已知的是前 i i i 个元素的和 f [ i ] ( 1 ≤ i ≤ n , 1 ≤ f [ i ] ≤ 100000 ) f_[i](1 \\le i \\le n, 1 \\le f[i] \\le 100000) f[i](1in,1f[i]100000),然后给出 Q ( Q ≤ 1000000 ) Q(Q \\le 1000000) 以上是关于❤️学姐说她用 8 行代码写了 8 个算法(上)❤️(推荐收藏)的主要内容,如果未能解决你的问题,请参考以下文章

熬夜帮学姐用Python完成词云图,没想到我好兄弟竟然...

熬夜帮学姐用Python完成词云图,没想到我好兄弟竟然...

区块链学姐:8月11日以太再破新高下,2000大关已不远

❤️学姐教我做游戏,一做便是十四载❤️

万字整理❤️8大排序算法❤️建议收藏

❤️导图整理大厂面试高频数组8: 移除元素的双指针优化, 力扣27❤️