Sonyfe25cp的玩具

home

感触+计划

27 May 2014

###感触

一个每天一起写代码的小伙伴最近给了自己很大的感触,距离上次这样的感触,已经有几年了吧好些好些日子了。

某天,我在写一个句子跟一组词组进行contains的计算,虽然这东西我也知道写一坨

for(String tmp : array){
	if(tmp.equals(key)){
	//blablabla
	}
}

是很不靠谱的,而且明显可以用个其他结构如Trie树,Map结构来实现。可懒得动脑子,顺手就这么写了。

小伙伴貌似在忍了很久之后,花了一会儿工夫给我写了个Trie树,然后我就用上了其实也没那么麻烦的数据结构

此时,我觉得自己确实有点懒很尴尬,为什么明知道可以做好,却不去做到最好呢。。

根小伙伴讨论了一下,当他坚持要帮我写个Trie树的时候,自己也决定写一个。可自己还在纠结边界条件的时候,小伙伴的测试都写完了。

艾玛,看了小伙伴的代码之后,发现自己的思维固定在教科书上的结构了,对于快速实现数据结构的时候,应该利用起语言的特点和其附带的结构。

代码对比:

class TrieNode{
public char word;
public List<TrieNode> nodes;
}
class Trie{
public char word;
public Map<Character, Trie> map;
}

上面的代码是我的,下面的是小伙伴的。

第一种写法,以节点出发,需要考虑很多边界条件,虽然会节省空间,可边界条件很多,比较费时。

第二种写法,从整体递归结构出发,代码简单了不是一点半点哦。

中午吃饭的时候,小伙伴问我有没有实现过并行排序,我想了一下,觉得多路合并就算是并行排序了。下午约3点的时候,小伙伴兴奋的告诉我多路排序写完了。

解决方法比较传统,对一个长数组,切割成多份,每一份进行快排,得到多份有序的数组,然后多路合并。

解决的细节是我没想到的,在快排的时候,传统都是先比较a==b,然后a 《 b or a》b 的判断。小伙伴对比了三种写法,然后用测试用例来看了一下耗时。结果是:快排先判断 a《b or a》b 再判断a==b最快,毕竟少比较一次。

原本的目标是:对多个字符串进行字母排序。对比一个int[]排序的区别就是从char[]变成int[],其实也就是comparator的变化。

小伙伴做了个意料之外的事情:测试。通过new int[10240000]这样的方式,再赋值随机数,然后测试自己的方法,比较array[i]和array[i+1]的方式来验证自己的算法。然后直接替换comparator到字符串排序中。这个还是很赞的。

当有一个巨大的文本在这里,需要统计其中的n-gram或者统计文本里某个词出现的词数。

我的直观的做法:遍历一遍文本,然后count有多少个。

优点:简单。

缺点:效率不高,当统计的词很多的时候,代码也会写的比较丑(基本就是俩数组挨个统计了)。

小伙伴想了个有意思的方法:例句,我爱北京天安门,天安门上太阳升。

变成:

我爱北京天安门,天安门上太阳升。

爱北京天安门,天安门上太阳升。

北京天安门,天安门上太阳升。

京天安门,天安门上太阳升。

天安门,天安门上太阳升。

安门,天安门上太阳升。

门,天安门上太阳升。

,天安门上太阳升。

天安门上太阳升。

安门上太阳升。

门上太阳升。

上太阳升。

太阳升。

阳升。

升。 。

对上面这一堆字符串进行排序,这样就可以得到一个下面这种结果:

,天安门上太阳升。

爱北京天安门,天安门上太阳升。

安门,天安门上太阳升。

安门上太阳升。

北京天安门,天安门上太阳升。

京天安门,天安门上太阳升。

天安门,天安门上太阳升。

天安门上太阳升。

门,天安门上太阳升。

门上太阳升。

上太阳升。

太阳升。

阳升。

从这个排序的结果上,就显而易见了。如果需要统计两个字,那么只取前两个字计算(找到这两个字的上面有多少个,然后找到下标,然后做差)。如果要计算n-gram,只要让窗口变成n这么大就行了。

这样做在统计n-gram时效率比较高,毕竟改一下窗口就可以随便计算了。而且可以控制内存的使用,这里只需要记录原文和每个字对应的下标(int[])。

处理速度可以通过数据排序的速度来控制。

尼玛,投稿APWEB的论文又悲剧了。

这是触动最大的了。。

###计划

不能太丢博士的脸见贤思齐的驱使,闲着没事就看看算法吧。复习一下各种基础数据结构的实现和常用算法实现尤其是各种排序算法

多看论文,别无他解。

还有好多项目的代码都是懒得调优,这尼玛怎么能有进步又不给钱优化个蛋

###综上

少打游戏,多看书!