1. 通俗地讲

  • 算法是解决计算问题的方法

2. 算法的五大特性

  1. 输入总数 >= 0
  2. 输出数量 >= 1
  3. 有穷性
  4. 确定性
  5. 可行性

3. 众所周知的“公式”

程序 = 数据结构 + 算法

4. 举个例子

例 1. 百钱买百鸡

公鸡,五钱一只;母鸡,三钱一只;小鸡,一钱三只。

一百钱买一百只鸡,如何买?

1. 数学解法

解:设购买公鸡 x 只,母鸡 y 只,小鸡 z 只

\[\left\{ \begin{aligned} x + y + z = 100 \\ 5x + 3y + \frac z3 = 100 \end{aligned} \right.
\]

2. C 的解法

#include <stdio.h>

void buy_chicken();

int main() {
buy_chicken(); return 0;
} void buy_chicken() {
int cocks = -1, hens, chicks;
while (cocks < 20) {
cocks++;
hens = -1;
while (hens < 33) {
hens++;
chicks = 100 - cocks - hens;
if (chicks % 3) {
continue;
}
if (5*cocks + 3*hens + chicks/3 == 100) {
printf("百钱可买公鸡 %2d 只,母鸡 %2d 只,小鸡 %d 只\n", cocks, hens, chicks);
}
}
}
}

3. Python 的解法

# coding:utf-8

def buy_chicken():
for cocks in range(20):
for hens in range(33):
chicks = 100 - cocks - hens
if chicks % 3 == 0 and 5*cocks + 3*hens + chicks//3 == 100:
print(f"百钱可买公鸡 {cocks:>2} 只,母鸡 {hens:>2} 只,小鸡 {chicks} 只")
return None if __name__ == "__main__":
buy_chicken()

4. Java 解法

public class BaiJiwenti {
public static void main(String[] args) {
buy_chicken();
} public static void buy_chicken() {
for (int x=0; x<20; x++) {
for (int y=0; y<33; y++) {
int z = 100 - x - y;
if (z % 3 == 0 && (5*x + 3*y + z/3 == 100 )) {
System.out.printf("百钱可买公鸡 %2d 只,母鸡 %2d 只,小鸡 %d 只\n", x, y, z);
}
}
}
}
}

5. 小结

  • 对于“百鸡问题”这一类甚至更多的问题,虽然不同语言的语法不尽相同,但解起来思路一致,关键几句更是如出一辙

5. 算法衡量

  • 衡量算法应该剔除机器配置,运算数量等无关因素

5.1 有这样两个指标

  • 时间复杂度 T(n)
  • 空间复杂度 S(n)

5.2 大 O 记法

  • 对于单调的整数函数,如果存在一个整数函数 g 和实常数 c (c>0),使得对于充分大的 n 总有

    f(n) <= c * g(n)

    即函数 g 是 f 的一个渐进函数(忽略常数),记为 f(n) = O(g(n))

    即在趋向无穷的极限意义下,函数的增长速度受到函数 g 的约束

    即函数 f y与函数 g 的特征相似

5.3 时间复杂度及其他

5.3.1 定义

  • 假设存在函数 g,使得算法 A 处理规模为 n 的问题示例所用时间为 T(n) = O(g(n)),则称 O(g(n)) 为算法 A 的渐进时间复杂度,简称时间复杂度,记为 T(n)

5.3.2 此外,还有

  1. 最优时间复杂度
  2. 最坏时间复杂度
  3. 平均时间复杂度
  • 一般关注最坏时间复杂度

5.3.3 时间复杂度计量规则

  • 基本操作,如只有常数项, 时间复杂度是 1
  • 顺序结构,时间复杂度按加法计算
  • 循环结构,按乘法计算
  • 分支结构, 取最大值
  • 得到一个方程式,然后在做化简,取方程的阶

5.3.4 判断一个算法的效率

  • 关注操作数量的最高次项,其余可忽略
  • 若没特殊说明,我们所分析的算法时间复杂度一般指最坏的复杂度

5.3.5 其他

  • “大样本统计方法”、“渐进等价”、“渐进展开”等数学概念我就略过了
  • 题外话:大家都知道“复”应该读第四声,但在这个短语中“复”读第三声超顺;类似的还有“标志符”、“char”等

6. 举例分析

# coding:utf-8

import sys
from time import perf_counter_ns def cal_time(func):
def in_():
start = perf_counter_ns()
name = func()
stop = perf_counter_ns()
print(f">>> {name}'s cost times: {stop - start}\n")
return in_ @cal_time
def solve1():
for cocks in range(101):
for hens in range(101):
for chicks in range(301):
if cocks + hens + chicks == 100 \
and 5*cocks + 3*hens + chicks/3 == 100:
print(f"公鸡 {cocks:>2} 只,母鸡 {hens:>2} 只,小鸡 {chicks} 只")
return sys._getframe().f_code.co_name @cal_time
def solve2():
for cocks in range(20):
for hens in range(33):
chicks = 100 - cocks - hens
if chicks % 3 == 0 and 5*cocks + 3*hens + chicks//3 == 100:
print(f"公鸡 {cocks:>2} 只,母鸡 {hens:>2} 只,小鸡 {chicks} 只")
return sys._getframe().f_code.co_name if __name__ == "__main__":
solve1()
solve2()
  • 不同的机子运算速度不同,但可以肯定的是 solve2() 比 solve1() 快,而且快挺多
  • 简单地说,solve1() 的循环嵌套比 solve2() 的多一层,这就决定了它的时间复杂度要多一个幂次
    • solve1() 的 T(n) = O(mnk)
    • solve2() 的 T(n) = O(mn)

[DS+Algo] 001 先简单说说算法的更多相关文章

  1. 基于BP神经网络的简单字符识别算法自小结(C语言版)

    本文均属自己阅读源代码的点滴总结.转账请注明出处谢谢. 欢迎和大家交流.qq:1037701636 email:gzzaigcn2009@163.com 写在前面的闲话: 自我感觉自己应该不是一个非常 ...

  2. 简单排序算法 C++类实现

    简单排序算法: 冒泡排序 插入排序 选择排序 .h代码: // // SortClass.h // sort and selection // // Created by wasdns on 16/1 ...

  3. 简单排序算法设计(Java)

    总共有八种排序算法,还是慢慢看吧 1.简单排序算法 简单排序算法就是设置标兵,逐个比较数,然后查找插入位置,插入 public static void p(int[] a){ for(int i=0; ...

  4. 简单的算法题, Find Minimum in Rotated Sorted Array 的Python实现。

    简单的算法题, Find Minimum in Rotated Sorted Array 的Python实现. 题目: Suppose a sorted array is rotated at som ...

  5. 一个简单的算法,定义一个长度为n的数组,随机顺序存储1至n的的全部正整数,不重复。

    前些天看到.net笔试习题集上的一道小题,要求将1至100内的正整数随机填充到一个长度为100的数组,求一个简单的算法. 今天有空写了一下.代码如下,注释比较详细: using System; usi ...

  6. 教你用Python实现简单监督学习算法

    教你用Python实现简单监督学习算法 监督学习作为运用最广泛的机器学习方法,一直以来都是从数据挖掘信息的重要手段.即便是在无监督学习兴起的近日,监督学习也依旧是入门机器学习的钥匙. 这篇监督学习教程 ...

  7. 简单数学算法demo和窗口跳转,关闭,弹框

     简单数学算法demo和窗口跳转,关闭,弹框demo <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&quo ...

  8. [DS+Algo] 005 三种简单排序及其代码实现

    目录 1. 冒泡排序 BubbleSort 1.1 算法描述 1.2 性能分析 1.3 Python 代码实现 2. 选择排序 SelectionSort 2.1 算法描述 2.2 选择排序的主要优点 ...

  9. [DS+Algo] 006 两种简单排序及其代码实现

    目录 1. 快速排序 QuickSort 1.1 步骤 1.2 性能分析 1.3 Python 代码示例 2. 归并排序 MergeSort 2.1 步骤 2.2 性能分析 2.3 Python 代码 ...

随机推荐

  1. Kendo UI for jQuery使用教程:支持Web浏览器

    [Kendo UI for jQuery最新试用版下载] Kendo UI目前最新提供Kendo UI for jQuery.Kendo UI for Angular.Kendo UI Support ...

  2. Puppet利用Nginx多端口实现负载均衡

    随着公司应用需求的增加,需要不断的扩展,服务器数量也随之增加,当服务器数量不断增加,我们会发现一台puppetmaster压力大,解析缓慢,而且时不时出现"time out"之类的 ...

  3. Docker(六):Dockerfile命令详解

    Dockerfile 指令详解 1 FROM 指定基础镜像 FROM 指令用于指定其后构建新镜像所使用的基础镜像.FROM 指令必是 Dockerfile 文件中的首条命令,启动构建流程后,Docke ...

  4. IP地址(参考百度百科)

    题目1:用子网掩码划分网络时,如果划分8个子网,则需要4位.因为24-2>=8.(全0代表网络自身,全1代表广播地址,所以减2) 以C类地址为例,(1)8个子网,则4位子网,主机号为后4位,主机 ...

  5. org.springframework.web.servlet.view.ContentNegotiatingViewResolver

    restful服务中一个重要的特性就是一种资源可以有多种表现形式,在springmvc中可以使用ContentNegotiatingViewResolver这个视图解析器来实现这种方式. 描述资源的三 ...

  6. jsp+servlet怎么实现文件断点上传下载

    我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用. 这次项目的需求: 支持大文件的上传和续传,要求续传支持所有浏览器,包括ie6,ie7,i ...

  7. ASP.NET实现文件断点续传

    IE的自带下载功能中没有断点续传功能,要实现断点续传功能,需要用到HTTP协议中鲜为人知的几个响应头和请求头. 一. 两个必要响应头Accept-Ranges.ETag 客户端每次提交下载请求时,服务 ...

  8. Codeforces 919E Congruence Equation ( 数论 && 费马小定理 )

    题意 : 给出数 x (1 ≤ x ≤ 10^12 ),要求求出所有满足 1 ≤ n ≤ x 的 n 有多少个是满足 n*a^n  = b ( mod p ) 分析 : 首先 x 的范围太大了,所以使 ...

  9. c++11相关特性

    前言 发现好多情况下都会用到c++11的新特性啊. 所以稍稍总结一下,只会粗略的说,不会详细的讲…… upd.csp-s可能不是c++11标准,请慎用.(博主考试CE后的善意提醒) 1.auto&am ...

  10. Netty 介绍和应用场景(一)

    1.为什么选择Netty 需要了解了Socket通信(IO/NIO/AIO)编程,对于通信模型已经有了一个基本的认识.,果想把这些真正的用于实际工作中,那么还需要不断的完善.扩展和优化.比如经典的TC ...