算法的特点:
特点 | 含义 |
---|---|
输入 | 待处理的信息(问题) |
输出 | 经处理的信息(答案) |
正确性 | 的确可以解决指定的问题 |
确定性 | 任意算法都可以描述为一个由基本操作组成的序列(即无二义性) |
可行性 | 每一个基本操作都可以实现,在常数时间内完成 |
有 穷 性 \color{red}{有穷性} 有穷性 | 对于任何输入,经过有穷次基本操作,都可以得到输出(此点非常重要但是又不好证明) |
… | … |
对于一个确定的程序,未必就是算法,比如死循环之类的程序。给定的一个程序,也无法确定是否是一个算法,比如冰雹序列,无法证明对于任意的输入规模 n n n该序列都是有穷的。下列给出冰雹序列的定义以及长度和序列的求解代码:
h a i l s t o n e ( n ) = { 1 n = 1 3 n + 1 n 为 奇 数 n / 2 n 为 偶 数 hailstone(n) =\left \{ \begin{array}{rcl} 1 & &n=1\\ 3n+1 & &n为奇数\\ n/2 & &n为偶数 \end{array} \right. hailstone(n)=⎩⎨⎧13n+1n/2n=1n为奇数n为偶数
#include <iostream>
#include <cstdio>
using namespace std;
// 获取冰雹序列长度
int hailstone(int n)
{
int length = 1;
while (n > 1)
{
n % 2 ? n = 3 * n + 1 : n %= 2;
length ++;
}
return length;
}
// 输出冰雹序列
void print_hailstone(int n)
{
printf("%d ", n);
if (n > 1)
if (n % 2)
print_hailstone(3 * n + 1);
else
print_hailstone(n / 2);
}
int main()
{
int n;
cin >> n;
cout << "Length: " << hailstone(n) << endl;
cout << "Sequence:";
print_hailstone(n);
return 0;
}
其中这里我们无法去证明 ∣ h a i l s t o n e ( n ) ∣ < ∞ |hailstone(n)|<\infty ∣hailstone(n)∣<∞,所以也无法确定这是否为一个算法。
好的算法具有的特点:
特点 | 含义 |
---|---|
正确 | 符合语法,能够编译、链接。 能够正确处理 { 简 单 ∣ 大 规 模 ∣ 一 般 性 ∣ 退 化 ∣ 任 意 合 法 } \color{red}{\{简单|大规模|一般性|退化|任意合法\}} {简单∣大规模∣一般性∣退化∣任意合法}的输入 |
健壮 | 能辨别不合法的输入并做适当处理,而不致非正常退出 |
可读 | 结构化 + 准确命名 + 注释 + … |
效率 | 速度尽可能快,存储空间尽可能少 A l g o r i t h m + D a t a s t r u c t u r e s = P r o g r a m s ( a l g o r i t h m + D a t a s t r u c t u r e s ) × E f f i c i e n f y = C o m p u t a t i o n Algorithm + Datastructures = Programs \\(algorithm + Datastructures) \times Efficienfy = Computation Algorithm+Datastructures=Programs(algorithm+Datastructures)×Efficienfy=Computation |
问题实例的 规 模 \color{red}{规模} 规模,往往是决定计算成本的 最 主 要 \color{red}{最主要} 最主要因素。
图灵机
(
T
u
r
i
n
g
M
a
c
h
i
n
e
)
(Turing \space Machine)
(Turing Machine)
构成部件:
部件 | 作用 |
---|---|
Tape | 依次均匀的划分单元格,各存有某一字符,初始化均为“#” |
Head | 总是对准某一单元格,并可读取或改写其中的字符 每经过一个节拍,可转向左侧或右侧的邻格 |
Alphabet | 字符的种类有限 |
State | TM总是处于有限种状态的某一种 每经过一个节拍可按照规则转向另一种状态 |
Transition Function:
(
q
,
c
;
d
,
L
/
R
,
p
)
(q, c; d, L/R, p)
(q,c;d,L/R,p)
使用图灵机实现非负整数加1:
(<, 1; 0, L, <) // 左行, 1->0
(<, 0; 1, R, >) //掉头, 0->1
(<, #; 1, R, >) //掉头, #->1, 二进制最高位为1时进位
(>, 0; 0, R, >) //右行, 直到遇到#
(>, #; #, L, h) // 复位
RAM
(
R
a
n
d
o
m
A
c
c
e
s
s
M
a
c
h
i
n
e
)
(Random\space Access \space Machine)
(Random Access Machine)
使用RAM实现Floor Division
(
⌊
c
/
d
⌋
)
(\lfloor c/d \rfloor)
(⌊c/d⌋)
0 R[0] <- 1 //increment
1 R[1] <- R[1] + R[0] // c++
2 R[1] <- R[1] - R[3] // c -= d
3 R[2] <- R[2] + R[0] // res += 1
4 IF R[1] > 0 GOTO 2 // if c > 0 goto 2
5 R[2] <- R[2] - R[0] // res = res - 1
6 STOP // return res