- 帖子
- 3151
- 积分
- 6455
- 技术
- 317
- 捐助
- 70
- 注册时间
- 2008-8-3
|
[挑战]100G文本统计+排序
本帖最后由 523066680 于 2019-1-30 11:16 编辑
源自ChinaUnix一个用户提出的问题,当时帮题主理清基础的处理方式,但是上G的文件依然没有写出高效率的代码。
原帖1,先从较简短的示例描述
http://bbs.chinaunix.net/thread-4263348-1-1.html
Windows19 发表于 2017-06-20 10:54
有几百GB,LOG,乱出八粗的
找出在文本内重复字符串从多到少打印,
找出重复次数最多字符串,然后整行打印 (注: 按2种类型条件判断统计,重复字母串次数,重复数字串次数,然后由多到少整行打印出来). 剩余的行也需一并打印出来(出来结果应和原LOG行数一致)
找出两种类型字符串在文本中重复最多次数,从多到少排序
a.txt- 65425855662efssaezsdfcsf//sff.sdf/'s;f]\sDed33dds3
- 65425855662efssaezsdfcsf/ /sff.sdf/'s;f] \sDed33sdds1
- yjyjgwwwghfg56www g.tgjgcom445.5454.'55.4l5
- efssaezsdfcsf//58969752sff.sdf/'s;f]\sDed33sds0
- efssaezsdfcsf/ 58969752/sff.sdf/'s;f] \sDed33sdds5
- 65425855662efssaezsdfcsf/ /sff.sdf/'s;f] \sDed33s00000000
- 65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com
复制代码 按条件统计后应该得到(人工审核不知道有没错)- 65425855662efssaezsdfcsf//sff.sdf/'s;f]\sDed33dds3
- 65425855662efssaezsdfcsf/ /sff.sdf/'s;f] \sDed33sdds1
- 65425855662efssaezsdfcsf/ /sff.sdf/'s;f] \sDed33s00000000
- efssaezsdfcsf//58969752sff.sdf/'s;f]\sDed33sds0
- efssaezsdfcsf/ 58969752/sff.sdf/'s;f] \sDed33sdds5
- 65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com
- yjyjgwwwghfg56www g.tgjgcom445.5454.'55.4l5
复制代码
这个题主是个典型的令人头痛的类型,因为他不把问题描述完整,一开始还发过几个简化过的问题的帖子,等到有人回复,他又渐渐把完整的问题浮出水面(可能有些细节他自己都不确定)
我在另一个帖子对处理方案做了详细说明,题主认为符合需求,可供参考:
523066680 发表于 2017-06-22 23:12
以原贴的段落为例,
[0]65425855662efssaezsdfcsf//sff.sdf/'s;f]\sDed33dds3
[1]65425855662efssaezsdfcsf/ /sff.sdf/'s;f] \sDed33sdds1
[2]yjyjgwwwghfg56www g.tgjgcom445.5454.'55.4l5
[3]efssaezsdfcsf//58969752sff.sdf/'s;f]\sDed33sds0
[4]efssaezsdfcsf/ 58969752/sff.sdf/'s;f] \sDed33sdds5
[5]65425855662efssaezsdfcsf/ /sff.sdf/'s;f] \sDed33s00000000
[6]65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com
处理结果:
[1]65425855662efssaezsdfcsf/ /sff.sdf/'s;f] \sDed33sdds1
[0]65425855662efssaezsdfcsf//sff.sdf/'s;f]\sDed33dds3
[5]65425855662efssaezsdfcsf/ /sff.sdf/'s;f] \sDed33s00000000
[4]efssaezsdfcsf/ 58969752/sff.sdf/'s;f] \sDed33sdds5
[3]efssaezsdfcsf//58969752sff.sdf/'s;f]\sDed33sds0
[6]65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com
[2]yjyjgwwwghfg56www g.tgjgcom445.5454.'55.4l5
每行的关键字在全文中出现的次数统计(单行内多次计为一次)
f(6),efssaezsdfcsf(5),sff(5),s(5),sDed(5),33(5),sdf(5),65425855662(4),3(1),dds(1)
f(6),s(5),sff(5),efssaezsdfcsf(5),33(5),sdf(5),sDed(5),65425855662(4),sdds(2),1(1)
5(3),g(2),www(2),yjyjgwwwghfg(1),56(1),445(1),tgjgcom(1),4(1),l(1),5454(1),55(1)
f(6),33(5),sdf(5),sDed(5),s(5),sff(5),efssaezsdfcsf(5),58969752(2),0(1),sds(1)
f(6),efssaezsdfcsf(5),sff(5),s(5),sDed(5),33(5),sdf(5),5(3),sdds(2),58969752(2)
f(6),efssaezsdfcsf(5),s(5),sff(5),sDed(5),sdf(5),33(5),65425855662(4),00000000(1)
f(6),65425855662(4),5(3),g(2),www(2),x(1),ftfr(1),e(1),com(1),54(1),t(1),ty(1),fsfsf(1),grytryg(1),efs(1),r(1),6(1),saezsdf(1)
处理后的顺序(按行排序,从最高的频率开始对比;如果最高的次数相同,则对比第二列,以此类推)
f(6),s(5),sff(5),efssaezsdfcsf(5),33(5),sdf(5),sDed(5),65425855662(4),sdds(2),1(1)
f(6),efssaezsdfcsf(5),sff(5),s(5),sDed(5),33(5),sdf(5),65425855662(4),3(1),dds(1)
f(6),efssaezsdfcsf(5),s(5),sff(5),sDed(5),sdf(5),33(5),65425855662(4),00000000(1)
f(6),efssaezsdfcsf(5),sff(5),s(5),sDed(5),33(5),sdf(5),5(3),sdds(2),58969752(2)
f(6),33(5),sdf(5),sDed(5),s(5),sff(5),efssaezsdfcsf(5),58969752(2),0(1),sds(1)
f(6),65425855662(4),5(3),g(2),www(2),x(1),ftfr(1),e(1),com(1),54(1),t(1),ty(1),fsfsf(1),grytryg(1),efs(1),r(1),6(1),saezsdf(1)
5(3),g(2),www(2),yjyjgwwwghfg(1),56(1),445(1),tgjgcom(1),4(1),l(1),5454(1),55(1)
纯数字,前后对比:
Before:
[0]6,5,5,5,5,5,5,4,1,1
[1]6,5,5,5,5,5,5,4,2,1
[2]3,2,2,1,1,1,1,1,1,1,1
[3]6,5,5,5,5,5,5,2,1,1
[4]6,5,5,5,5,5,5,3,2,2
[5]6,5,5,5,5,5,5,4,1
[6]6,4,3,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1
After
[1]6,5,5,5,5,5,5,4,2,1
[0]6,5,5,5,5,5,5,4,1,1
[5]6,5,5,5,5,5,5,4,1
[4]6,5,5,5,5,5,5,3,2,2
[3]6,5,5,5,5,5,5,2,1,1
[6]6,4,3,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1
[2]3,2,2,1,1,1,1,1,1,1,1
注意上面的结果是同一“单词”在单行中重复多次记为一次的。应考虑按多次计算的情况(或者做个开关允许按不同方式处理)
65425855662efssaezsdfcsf/ /sff.sdf/'s;f] \sDed33s00000000
一行内两次算是2次吗?我以为一行内多次也计为1次,还特地做了判断
Windows19 回复 53# 523066680
如果算2次影响效率
那在一行内出现相同的算1次也可以
当然这个细节不是主要问题,数据量大以后要考虑哈希表的内存占用,如果改用文件存储数据结构,则需要考虑效率、硬盘占用问题。
"分而治之"策略 和 归并排序 应该是少不了的,个人认为是很好的锻炼。
当时(17年)的代码虽然借用DB_File模块支持了大文件处理,但效率极低,正打算重写。
为了减少过度的测试时间和硬盘消耗,将此问题稍作修改,改为10G文件(或1G),语言不限,大家有兴趣吗? |
|