2020-04
18

死磕二分法搜索

By xrspook @ 15:00:07 归类于: 扮IT

我是看着题目的中文版做题的

练习10:要检查一个单词是不是在上面这个词汇列表里,你可以使用 in 运算符,但可能会很慢,因为这个 in 运算符要从头到尾来搜索整个词汇表。我们知道这些单词是按照字母表顺序组织的,所以我们可以加速一下,用一种对折搜索(也叫做二元搜索),这个过程就和你在现实中用字典来查单词差不多。你在中间部分开始,看看这个要搜索的词汇是不是在中间位置的前面。如果在前面,就又对前半部分取中间,继续这样来找。当然了,不在前半部分,就去后半部分找了,思路是这样的。不论怎样,每次都会把搜索范围缩减到一半。如果词表包含了113809个单词,最多就是17步就能找到单词,或者能确定单词不在词汇表中。那么问题来了,写一个函数,名为 in_bisect,接收一个整理过的按照字母顺序排列的列表,以及一个目标值,在列表中查找这个值,找到了就返回索引位置,找不到就返回空。

做到死去活来词语在词汇表里有索引正确,没有时却会疯掉的时候我不得不去看答案,看到答案后傻眼了,答案对单词的判断只有True和False,再去找原题,我那个去,题目改了!不要求索引了好吗!

Exercise 10: To check whether a word is in the word list, you could use the in operator, but it would be slow because it searches through the words in order. Because the words are in alphabetical order, we can speed things up with a bisection search (also known as binary search), which is similar to what you do when you look a word up in the dictionary (the book, not the data structure). You start in the middle and check to see whether the word you are looking for comes before the word in the middle of the list. If so, you search the first half of the list the same way. Otherwise you search the second half. Either way, you cut the remaining search space in half. If the word list has 113,809 words, it will take about 17 steps to find the word or conclude that it’s not there. Write a function called in_bisect that takes a sorted list and a target value and returns True if the word is in the list and False if it’s not. Or you could read the documentation of the bisect module and use that! Solution: http://thinkpython2.com/code/inlist.py.

又纠结一番后我终于写出了一句“first > last”返回例外情况,终于,世界被拯救了!记录索引和不记录索引很不一样啊,按照参考答案的解法,i即便返回也永远是1,索引无能。纠结是有好处的,让我明白到二分法搜索有多么的高效,简直甩while循环几十条街,但如果真索引的话,估计我会很懒地直接用list.index(),虽然用之前必须用in历遍列表,判断是否存在。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import time
def in_bisect(library, first, last, myword): # 二分法搜索,10万数据查询最多只需不到20步
    if first > last: # 这是一句拯救了我的条件
        return None
    else:
        mid = (first + last)//2
        if myword == library[mid]:
            return mid
        elif library[mid] > myword:
            return in_bisect(library, first, mid-1, myword)
        else:
            return in_bisect(library, mid+1, last, myword)
myword = 'zoo' # input('myword is: ')
i = 0
library = []
fin = open('words.txt')
for line in fin:
    word = line.strip()
    library.append(word)
library.sort()
start = time.time()
 
# j = 0
# while i < len(library) - 1: # 我的脑洞第一反应用的循环
#     if myword == library[i]:
#         j = i
#         break
#     i += 1
# if j == 0:
#     print('myword is not in library')
# else:
#     print('index =', j)
 
# if myword in library: # 伟大列表自带的查询索引号,但先得确定单词在那里
#     i = library.index(myword, 0, len(library)-1)
# if i == 0:
#     print('myword is not in library')
# else:
#     print('index =', i)
 
if in_bisect(library, 0, len(library), myword) == None: 
    print('myword is not in library')
else:
    print('index =', in_bisect(library, 0, len(library), myword))
end = time.time()
print(end-start)
# myword is not in library while 0.07   index 0.003  bisect 0.001
# apple 4450               while 0.003  index 0.001  bisect 0.001
# zoo 113707               while 0.07   index 0.005  bisect 0.001
# while,index和bisect没有对比就没有伤害
2016-10
16

总有路

By xrspook @ 21:31:11 归类于: 烂日记

你永远都猜不到前方有什么奇葩事情在等待你,哪怕你正在做的事你每天都要做,或者你这辈子已经做过很多很多次。比如说在刻Lucha Underground logo的橡皮章之前,我已经刻过超过50个,但那一次,我也不知道为什么居然刻刀切手指了,我自己却毫不知情。直到看到白色的橡皮上出现铁红色,我才恍然大悟。比如说上个周六跑的18K我的心率不知为什么在几K后就飙到了160以上。我已经在那条路线上跑过非常多的18K,合计超过80次,无论是盛夏还是严冬,无论是下雨还是烈日,都没发生过那种事。比如上周在单位我跪在垫子上的时候,脚后跟无论如何碰不到屁股,但今天做完普拉提以后我却发现我跪在瑜伽垫上轻易地做到了。再比如说我已经用Yamb MP4Tools剪过很多视频,也用MeGUI压过很多视频,但今天当我想把字幕通过MeGUI压进剪切出来的mp4的时候,却无论如何都做不到。软件在开始压制之前,已经崩溃了。我的第一个反应是,会不会是因为软件没有做更新?但更新完毕后还是那样。我在官方网站上重新下载,结果还是一致。这是视频源的问题?软件的问题?压制参数的问题?还是电脑开机开太久了,需要歇一下?如果重启电脑就能把这一些都解决,我愿意那么做。但我的直觉告诉我,应该不是那么回事。我要压制的视频是1080p的,虽然实际上那个视频并没有这么高的分辨率,因为从油管上抓取下来1920*1080的视频接近两个半小时,大小却只有2.7GB不到。对1989年的电影,我们实在不能强求太多了,当时还没有什么高清摄像机。油管上的1080p肯定是有些问题的,但总比480p的马赛克好非常多。官方油管上的视频好处是不像普通人用DVD或BD压制那般,技术不好会出现拉丝。看过不少米叔八九十年代的电影后我觉得不知道为什么有一些镜头会很模糊,那应该不是压制的问题而是拍摄的时候对焦失误。这完全可以理解,想想十年前的那些数码相机,因为ISO不高,如果快门时间短到一定程度,又肯定会出现抖动,所以也就只能把光圈调小,光圈调小的后果就是构图里只有目标部分是清晰的,其它地方都有可能糊成一片。十年前的数码相机尚且如此,二十年前的老爷摄像机,估计也逃不出这个。

遇到问题,我觉得妈妈最喜欢在那里嚷嚷,甚至连问题都没说清就在那里嚷嚷!就像着火的时候打电话给119,一直吼,着火了,着火了,却不说到底是在哪里?是什么着火了?既然我觉得那个不好,我就不应该再做那种事。

视频压制不了的那个问题着急也没用。之前在压制DVD的时候我就试过一次,视频源直接拿去压,无论如何都不行。所以之前就得有一个把视频源新索引,然后用索引文件作为视频源输入压制的步骤。这次剪切出来的视频源为什么会压制失败?我发现其中一个现象是,预览的窗口视频的长度并不是我真正剪出来的那个长度,而是整个电影的全长。感觉这就是视频信息没有正确读取的问题。我把视频拿去索引所以然后去洗澡。洗澡回来发现弹出来的预览窗口视频终于正常了。这就意味着压制会成功。实在不知道,1080p的视频该用什么码率压制,于是就选择5000Kbps。出来的效果很不错,不过比之前剪出来的大了1倍而已。如果我的视频源真的是1080p,两个半小时的原视频大小能达到15GB以上,估计我得用8000才行。浏览过原视频播放时的信息,基本上只有少数镜头会超过5000,所以,我选择5000已经算是比较高端的了。

问题会不断出现,但人仍能将其不断地解决掉。不是因为突然发现了什么神器,或者有什么神人给你雪中送炭。过去所做的一切累积回来的经验都是要往后走得更好更快的基础。

所有的努力都不会白费。当质变发生的时候,并不是因为运气突然间变好了,而是因为量变达到了一定程度。

© 2004 - 2024 我的天 | Theme by xrspook | Power by WordPress