即是说:利用计算机,做你想做的任何的事。
培养一种本能:每当你面对一些技术问题的时候,本能之一是“我怎么才能编写一个代码,来帮我解决这个问题。
2.什么是知识?
陈述性的知识:事实陈述,阐述真相,是一个定义一个原理。
如 :
2y=x
程序性的知识:推断、演绎过程的描述,是一个方法,是一系列行为的描述。一串明确指令的续发事件,按顺序走完,沿途进行一些测试,并且按照测试的数值,改变在指令序列中我的位置,还有一个结束测试,告诉我什么时候完成和最终的结果是什么。
如 :
Start guess G 以一个猜想开始,把它称为G
if G*G >= X, stop 如果G的平方大于等于X,停止,回到G上
else G< X, (G+X)/2 有一个关于G的心猜想,就是X大于G,将二者相加除以2,得到一个大雨G的平均数
Repeat 新猜想
3.想象用环形线路去建立计算机程序捕捉一系列的计算
a、有几个变量
b、用导线把它们移来移去
c、一部分变量做加法,一部分变量做减法,一部分做除法,一部分做检查
(这个线路的输入设备可以是任意一个其他线路的流程)
4.Iterative
Programs(迭代程序)的思路:
a.选一个计数的变量count b.在循环初始化它 c.设置完结测试 d.构建循环代码(改变计数器的变量,防止无限循环) e.循环结束后做什么
例子:求一个完美平方数的平方根 先把求平方根的对象称为x 先从1开始,如果1的平方小于等于x,那么就跳到2,求2的平方,继续下去 直到一个整数的平方大于x,因为当大于x的时候已经经过了想要的答案,当得到一个数的平方等于x的时候,答案就出来了,可以跳出循环
在写代码之前先画个流程图(flowchart)
开始→设置ans(计数变量)→完结测试(y/n)
在循环中循环一定次数以得到正确答案,循环的次数取决于答案,因此当改变答案的时候,也就改变了代码的复杂度,这也是线性复杂度程序的一个例子,因为程序要循环的次数和输入的参数的大小直接相关,如果把参数乘2,那么进行循环的次数也会乘2
画完流程图该写代码了:
x = 16
ans = 0
while ans*ans <= x:
ans = ans + 1
print ans
1
2
3
4
5
模拟运行代码(simulate)也是debug的好方法:
这么一看感觉哪里不对劲,没错,bug出现了,很容易发现的bug,符号<=应该改为<
关于这块代码的两个问题: 1.对于x的什么值程序会最终终止 2.对于x的什么值程序会返回正确答案
如果x是负整数,程序在第一步就会停止 通过上面两个问题,就应该知道去检查程序是不是做了正确的操作的操作的能力,这就是在写每个循环程序的时候都要注意的两个事情: 1.确保程序可以终结 2.确保程序返回了正确的答案
来看看写这程序的更好方法:
ans = 0
if x >= 0:
while ans*ans < x:
ans = ans + 1
# print 'ans=', ans
if ans*ans != x:
print x, 'is not a perfect square'
else: print ans
else: print x, 'is a negative number'
1
2
3
4
5
6
7
8
9
10
这种更好的编程通常被叫做防卫性程序设计(defensive
programming),简单说就是确信在代码中涵盖了所有的可能路径或所有可能的输入,都对应了代码中的一个路径或者代码中有对应的处理方式,避免了错误或者无限循环的产生
5. 代码风格
Exhaustive
Enumeration: 尝试所有合理的值直到找到解决方案: 实际上遍历了一些参数的所有的可能的值,一些计算的元素,测试一切东西直到找到了正确的答案
假设我想找到一些整数的所有除数,我想要找出来这个数的所有的除数
x = 10
i = 1
while i < x:
if x%i == 0:
print 'divisor', i
i = i+1
1
2
3
4
5
6
对于某些数据的集合,我想要一个循环机制,现在我的过程就是通过一个个访问这个集合中的元素的方式来遍历这个集合,所以这个特定循环就成了FOR循环
for in <some collection>
1
使用x变量应用为占位符,用它来遍历这个集合,从第一个直到最后一个,这么做的好处是不用为更新变量发愁了,也不用去担心初始化变量和递增器,程序会自动的进行这个操作,下面是使用for循环的上例代码:
x = 10
for i in range(1, x):
if x %i == 0:
print 'divisor', i
1
2
3
4
5
for循环除了上面的优点,我们把它认为是一个整数的序列,可以认为它是按照数字依次来的(但实际上这些集合是可以任意的),我们可以换种方式来建立集合,而且它也可以是一个所有质数的集合或其他
由此我们要认识一个数据结构:元祖,它是一系列有序的元素,它是不变的 创建元祖的表达式:foo=(1,
2, 3, 4) 想要获取元祖中第一个值:foo[0] (索引是从0开头,-1是尾巴) 元祖可切片:
foo[1:3]
>>>(2, 3)
1
2
3
(从第二名到第四名为止,不算第四名)
x = 100
divisors = ()
for i in range(1, x):
if x%i == 0:
divisors = divisors + (i,)
1
2
3
4
5
6
这样就可以使用循环结构把数据放在集合中去了,那么字符串呢?
字符串是有序的字符序列,现在字符串不是用这种方式表达的,没有看到字符串里有开括号和闭括号,字符串中间也没有逗号,但它也是有序的字符序列,我们可以对字符串进行同样的操作(选择、切片)
看个栗子
sumDigits = 0
for c in str(1995):
sumDigits += int(c)
print sumDigits
1
2
3
4
先把数字转换成字符串,然后再用for循环从第一个字符开始进行转换为int型并加到sumDigits中
也许会问这些结构的集合能做什么,答案是基本上什么都可以,这是一个被称为是图灵完全化语言的特点的例子之一,也就是用这些结构你可以计算任何可以用算法描述的东西,不过真正困难的是如何构造解决特定问题的这些结构