给我一把榔头,满世界都是钉子

探讨了在处理大规模文本数据时,如何高效地找出重复次数最多的单词。文章对比了使用Hadoop MapReduce等分布式计算框架与直接内存计算的不同方法,并提出通过利用额外信息如单词的常见性进一步优化解决方案。

一篇文章存成一个巨大的文件,总共大约有一亿个单词,要找出里面重复次数最多的。怎么做?

Hadoop是一把威力巨大的榔头,在使用过Hadoop之后,看着任何东西都想把它给map reduce了。有一个关于Jeff Dean的小笑话,说在睡不着觉的时候,一般人是数羊,Jeff Dean是map reduce他的羊群。所以,我的办法是,把这个文件拆分成若干个小文件,在map过程用hash算法保证相同的单词落入一个文件(这点很重要),计算单词出现次数,在reduce过程取得重复次数最多的单词来。

但是,只有一亿个单词,简单估算一下,一个字母占据两个字节,假设单词平均长度5,即便是最极端情况,这些单词里面没有重复,单词本身也就消耗1G而已;而实际上一篇文章单词的重复率是非常高的,这个数据量完全可以放在内存里面计算。还没完,不一定非得要用Hash,如果借由Trie树,可以节点压缩,占用更少的空间。

这只是一个用榔头来敲钉子的一个小例子而已,在我刚学算法的时候,那时候刚接触外排序,这样的问题我或许会第一反应使用外排序来做,在那个时候,这把榔头就是外排序。但实际上呢,外排序的效率比上面提到的方法都低得多,只有在内存实在不够用的时候才适合考虑(即便在内存不够用的情况下,我们依然可以利用hash,把大文件划分成若干个小到内存可以容纳为止的文件,分别计算以后在来归并求最大数,目的就是要尽量避免外排序带来的大量磁盘读写)。

如果再把思路放宽一点,真的需要统计所有的单词吗?其实对于一篇文章来说,其中的内容都是有文字意义的,换言之,只有很少的单词可能成为“重复最多”的,这个数量应该是非常非常有限的。比如在遇到一个“is”的时候,我们知道要把它列入统计范畴,但是遇到“distribution”这样的词呢,大可跳过。

还可以找得到很多这样的榔头,比如概率公式,C(m,n)和A(m,n),即组合数和排列数,对于某些概率、混合、排列的问题就用它来套;再比如常见的榔头——动态规划,学了以后看到求最优解问题就很想用DP来解;还有在数据量很大的情况下利用hash、区域划分等等“分而治之”的化简思想……但是,这些都是常规思路,就如同Top K问题用堆排序来求解,寻找“不出现”的单词就使用bit map,“不重复出现”的单词就使用2-bit map等等这样的问题一样,终归是简单粗暴那一类的。即便解决了问题,也没有给人眼前一亮的“巧妙”的感觉。

跳出算法,在很多工程问题上也有类似的体会。记得以前在做一个项目的单元测试,Easy Mock + Easy Mock Extension + Power Mock,这样一套库,mock的能力实在强大,几乎没有测试不了的代码了,于是就拿了这把榔头到处砸,却忘了单元测试的最终目的是什么,那一些代码是值得做单元测试的。后来利用ant给测试环境中,不关心逻辑的那一层,使用自己写的桩代码mock掉,并且去掉了好多价值不大的测试代码(在代码更新的时候测试代码需要同步维护,这个成本不划算,所以我们把一些价值有但不大的单元测试用例合并或者删除了),层次反而更清楚,测试代码反而更易懂了。

前些日子和我们组的数学达人讨论问题的时候他说,我们最常见的最通用的榔头,主要还是在“解空间的搜索”和“解的构造”这两方面。如果能构造,复杂程度往往就要低于搜索,这是一个递进;而另一方面,任何一个实际问题都是有额外信息的,通用的榔头却是不考虑这些实际信息的,就像这个求重复次数最多的单词问题一样,文件有多大、文件内存放的是一篇实际有意义的文章,等等(再比如如果这个文件里面不是一亿个单词,而是一亿个整数呢),这些都是额外的信息,这是另一个递进。利用这些,简化了问题,就可以杀鸡不用牛刀了吧。

文章系本人原创,转载请保持完整性并注明出自《四火的唠叨》

<think>好的,我现在需要帮用户解决如何写一篇关于父亲的作文的问题。首先,我得分析用户的需求。用户可能是个学生,老师布置了写父亲的作文,需要指导。用户可能对如何结构、选材、表达情感不太清楚。 接下来,我应该考虑如何组织回答。根据用户的要求,需要分步骤或方法,避免使用“首先”、“然后”这样的词,所以得用不同的方法或角度来呈现。同时,要整合网络搜索的内容,确保信息实用可操作。 第一步,确定主题方向。可能的方向包括父爱、成长故事、特殊经历等。需要给出具体的例子,比如父亲的手、背影、教导的话,这样用户容易理解。 第二步,选材技巧。用户需要知道如何选择素材,可能包括日常细节、矛盾冲突、物品象征。比如生病照顾、教骑车、严厉的瞬间,这些具体场景能引发共鸣。 第三步,结构布局。总分总结构比较稳妥,开头可以用场景描写,中间分事件,结尾升华主题。可能需要例子,比如开头用厨房的声音,中间分三个事件,结尾用比喻句。 第四步,描写方法。要具体,比如外貌、语言、动作描写。给出例子,如父亲的外貌细节,语言的特点,习惯性动作,这些能让形象更生动。 第五步,情感升华。避免空泛,要联系实际。比如从父亲的教育方式学到道理,或者传承品质,这样的结尾更有深度。 然后,要检查是否符合格式要求:分点换行,没有第一人称,没有步骤词汇,引用分散。还要注意代码和公式的格式,但这里可能用不上。最后添加相关问题,确保三个问题相关,基于用户原始问题,比如开头技巧、避免俗套、情感表达方法。 可能还需要搜索一些写作技巧,比如如何选材,结构例子,描写方法的具体例子,确保内容准确。然后整合这些信息,用简洁清晰的语言呈现,确保每个方法都有例子,帮助用户实际操作。 最后,生成相关问题,考虑用户可能的后续疑问,比如如何开头,避免俗套,表达情感的方法,这些都能帮助用户进一步改进作文。</think>**关于父亲的作文写作指南** **一、确定主题方向** 选择具体切入点而非泛泛而谈,可从以下角度切入: - 父爱表达方式(如粗糙手掌温柔动作的对比) - 成长关键节点(中考陪读、学骑自行车等) - 特殊经历(暴雨送医、工地探访体验) - 传承关系(从抵触父亲习惯到理解认同) **二、选材技巧** 通过具体场景塑造人物形象: - 日常细节:清晨做早餐时佝偻的背影,修电器时专注的神态 - 矛盾冲突:严厉训斥考试成绩后深夜帮忙改错题 - 物品象征:总也舍不得换的旧皮带,珍藏多年的全家福照片 示例场景: ```text 父亲在台风天冒雨送准考证,湿透的衬衫贴着后背,准考证却在怀里用塑料袋裹了三层 ``` **三、结构布局** 推荐总分总结构: 1. 场景式开头:厨房飘来的葱花面香气,工具箱里的榔头声响 2. 主体分层展开: - 生活关怀(例:每天提前温好牛奶) - 品格影响(例:退还超市多找的零钱) - 精神传承(例:模仿父亲助人行为) 3. 结尾升华: $$父爱 = 沉默的土壤 + 永恒的光照$$ "父亲的皱纹是时光的沟壑,盛满了我成长的重量" **四、描写方法** 1. **外貌特写**: - 泛白鬓角新生白发占比 - 食指关节处的厚茧形成过程 2. **语言特征**: - 标志性口头禅("注意安全"变奏史) - 欲言又止的沉默时刻 3. **动作细节**: - 习惯性揉腰的小动作 - 藏起伤口时的仓促转身 **五、情感升华技巧** 1. 双线并置:将父亲现状年轻照片对比 2. 今昔呼应:重现场景(如再坐父亲自行车后座) 3. 文化意象:联系传统父亲形象(如朱自清《背影》) 4. 时代特征:农民工父亲智能手机使用困境
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值