问题:我有一个巨大的原始文本文件(假设为3G),我需要查看文件中的每个单词,并发现一个单词在文件中出现了多少次。
我提出的解决方案:将巨大的文件拆分成多个文件,每个拆分的文件都会以排序的方式包含单词。例如,以"a“开头的所有单词都将存储在"_a.dic”文件中。因此,我们在任何时候都不会执行超过26个文件。
这个方法的问题是,
我可以使用流来读取文件,但希望使用线程来读取文件的某些部分。例如,使用一个单独的线程读取0-1024字节(至少有基于no的4-8个线程)。在盒子里有处理器)。这是可能的还是我在做梦?
有更好的方法吗?
注意:它应该是一个纯c++或基于C的解决方案。不允许使用数据库等。
发布于 2009-10-26 15:08:10
你需要看看克尼汉和派克的“编程实践”,特别是第三章。
在C++中,使用基于字符串和计数的映射(std::map<string,size_t>,IIRC)。读取文件(一次--它太大了,不能读取不止一次),一边读一边把它分割成单词(对于“word”的某些定义),并在地图条目中增加您找到的每个单词的计数。
在C中,您必须自己创建映射。(或者找到大卫·汉森的“C接口和实现”。)
或者您可以使用Perl、Python或Awk (它们都有关联数组,相当于一个映射)。
发布于 2009-10-26 15:09:14
我不认为使用并行读取文件部分的多线程会有多大帮助。我希望这个应用程序绑定到硬盘的带宽和延迟,而不是实际的单词计数。这样的多线程版本执行起来可能会更糟,因为“准随机”文件访问通常比“线性文件”访问慢。
如果CPU在单线程版本中真的很忙,可能会加快速度。一个线程可以读取大量数据,并将它们放入容量有限的队列中。一组其他的工作线程可以在各自的块上操作并计算单词。计数工作线程完成后,您必须合并单词计数器。
发布于 2009-10-26 16:10:51
首先-决定保存单词的数据结构。
最明显的选择是地图。但是也许一个特瑞会更好地服务于你。在每个节点中,保存单词的计数。意思是,它只是一个单词的一部分。您可以使用流插入trie并读取基于字符的文件。
第二次多线程是还是不是?这个问题不容易回答。根据数据结构的大小以及并行化的方式,答案可能会有所不同。
有一件事你必须考虑--你必须为每个线程找到一个单词边界来启动,但这不会造成很大的问题(例如,每个线程一直走到第一个单词边界,然后在那里开始,每个线程在结束时完成它正在处理的单词)。
https://stackoverflow.com/questions/1625299
复制相似问题