Chinaunix

标题: 字符串排序 [打印本页]

作者: Windows19    时间: 2017-06-21 13:38
标题: 字符串排序
本帖最后由 Windows19 于 2017-06-21 22:58 编辑



有在shell版老师说叫我过来这看看   我也就过来了  



不限语言

原贴
http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=4263348&fromuid=29931773
(出处: http://bbs.chinaunix.net/)





简化描述贴
http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=4263390&fromuid=29931773
(出处: http://bbs.chinaunix.net/)


统计最多字符串进行重新排序

A.txt

a1
b2
1a
d3
a1a
7c
2a0
5b
c9
6b6


分2种统计类型  1种统计字母串   1种统计数字串  ,如果同时判断这2种条件类型, 可能会存在某种判断冲突  还是写统计一种类型吧,

1, 如果按字母串统计^[a-zA-Z]  其特征 a是文本内出现5次  b出现3次  c出现2次  d出现1次  所以得从多到小排序


2, 如果按数字串统计^[0-9]  其特征  1是文本内出现3次  2出现2次  6出现2次  5出现1次  9出现1次 7出现1次 3出现1次


如果按字母串统计, 出来后大概应该是这样排  

a1
1a
a1a
2a0
b2
5b
6b6
c9
7c
d3

谢谢


作者: quanpai    时间: 2017-06-21 15:05
抛砖引玉
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my %seen;
  5. while ( my $word = <DATA> ) {
  6.   chomp $word;
  7.   for my $char ( split("", $word) ) {
  8.       next if $char !~ /[a-zA-Z]/;
  9.       #next if $char !~ /[0-9]/;
  10.       $seen{$char}->{num}++;
  11.       push @{$seen{$char}->{word}}, $word;
  12.   }
  13. }

  14. my %print_seen;
  15. for my $char ( sort {$seen{$b}->{num} <=> $seen{$a}->{num}} keys %seen ) {
  16.     for my $word ( @{$seen{$char}->{word}}) {
  17.       next if $print_seen{$word}++;
  18.       print $word, "\n";
  19.     }
  20. }

  21. __DATA__
  22. a1
  23. b2
  24. 1a
  25. d3
  26. a1a
  27. 7c
  28. 2a0
  29. 5b
  30. c9
  31. 6b6
复制代码

作者: Windows19    时间: 2017-06-21 15:46
回复 2# quanpai

谢谢能写成定向到文件么
因文件超过百G,最好写成执行一个脚本就可以,这样可以不用嵌入文件内容

例如执行这样命令动行脚本  perl  123  A.txt  >log
这样可以直接定向到目标文件

作者: quanpai    时间: 2017-06-21 15:52
回复 3# Windows19

稍作改变:
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my %seen;
  5. open DATA, "<", shift;

  6. while ( my $word = <DATA> ) {
  7.   chomp $word;
  8.   for my $char ( split("", $word) ) {
  9.       next if $char !~ /[a-zA-Z]/;
  10.       #next if $char !~ /[0-9]/;
  11.       $seen{$char}->{num}++;
  12.       push @{$seen{$char}->{word}}, $word;
  13.   }
  14. }

  15. my %print_seen;
  16. for my $char ( sort {$seen{$b}->{num} <=> $seen{$a}->{num}} keys %seen ) {
  17.     for my $word ( @{$seen{$char}->{word}}) {
  18.       next if $print_seen{$word}++;
  19.       print $word, "\n";
  20.     }
  21. }

  22. close DATA;
复制代码



作者: quanpai    时间: 2017-06-21 15:57
回复 3# Windows19

文件超过百G的话,估计跑不出来
作者: Windows19    时间: 2017-06-21 16:03
回复 4# quanpai

Yes  非常好请能把数字串也一起判断统计么?



作者: Windows19    时间: 2017-06-21 16:19
本帖最后由 Windows19 于 2017-06-21 16:20 编辑

回复 4# quanpai

请问 如果同时可以统计字母串和数字串  可以实现下面结果吗?  会不会存在判断冲突
a.txt
1a
1j
1y
2a0
2u
5b
6b6
7c
a1
a1a
b2
c9
d3
g2



结果大概可以这样排序

a1
1a
a1a
1y
j1
1j
2a0
g2
2u
b2
5b
6b6
7c
c9
d3



作者: sunzhiguolu    时间: 2017-06-21 16:32
回复 2# quanpai
__DATA__
a1
b2
1a
a1
d3
a1a
7c
2a0
5b
c9
6b6
对于文本内容相同,但不同行的情况如何处理?能否继续抛砖引玉?


作者: 523066680    时间: 2017-06-21 16:36
本帖最后由 523066680 于 2017-06-21 16:41 编辑

如果文件过百G,可以考虑先遍历一次统计次数,然后再次从头遍历
逐行根据统计结果,分类导出到不同的文件,比如
sort_a.txt,
sort_b.txt
sort_c.txt
.....

这样就不用占用什么内存。都是线性地读取线性地导出。
完成这一步后可以进行合并

作者: Windows19    时间: 2017-06-21 16:54
回复 9# 523066680

4楼测试  内存全部吃光 死机了
作者: quanpai    时间: 2017-06-21 16:57
回复 8# sunzhiguolu

这样打印的时候需要记住行数
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my %seen;
  5. open DATA, "<", shift;

  6. my $count = 0;
  7. while ( my $word = <DATA> ) {
  8.   chomp $word;
  9.   for my $char ( split("", $word) ) {
  10.       next if $char !~ /[a-zA-Z]/;
  11.       #next if $char !~ /[0-9]/;
  12.       $seen{$char}->{num}++;
  13.       push @{$seen{$char}->{word}}, $count . "^^^^^" . $word;
  14.   }
  15.   $count++;
  16. }

  17. my %print_seen;
  18. for my $char ( sort {$seen{$b}->{num} <=> $seen{$a}->{num}} keys %seen ) {
  19.     for my $word ( @{$seen{$char}->{word}}) {
  20.       next if $print_seen{$word}++;
  21.       print((split(/\^\^\^\^\^/, $word))[1] . "\n");
  22.     }
  23. }

  24. close DATA;
复制代码



作者: quanpai    时间: 2017-06-21 16:59
回复 7# Windows19

  1. next if $char !~ /[a-zA-Z]/;
复制代码

改成

  1. next if $char !~ /[a-zA-Z0-9]/;
复制代码



作者: quanpai    时间: 2017-06-21 17:04
回复 10# Windows19

文件大的话按照9楼的就可以,主要原理就是不能存数据
作者: 523066680    时间: 2017-06-21 17:48
本帖最后由 523066680 于 2017-06-21 18:41 编辑
  1. =info
  2.     code by 523066680
  3.     2017-06
  4. =cut

  5. #!/usr/bin/perl
  6. use strict;
  7. use IO::Handle;
  8. STDOUT->autoflush(1);

  9. our $SRC = "A.txt";
  10. our $DST = "Final.txt";
  11. our %letter;
  12. our @group = ('a'..'z', 'A'..'Z');
  13. our $wd = "./tempfolder";
  14. mkdir $wd if (not -e $wd);

  15. ANALYSE_AND_EXPORT:
  16. {
  17.     my %FH;

  18.     #提前准备多个文件句柄
  19.     grep { open $FH{$_}, ">:raw", "$wd/T${_}.txt" or die "$!" } @group;

  20.     open READ, "<:raw", $SRC or die "$!";
  21.     while ( my $line = <READ> )
  22.     {
  23.         if ($line=~/([a-zA-Z])/)
  24.         {
  25.             $letter{$1} = 0 if ( not exists $letter{$1} );
  26.             $letter{$1}++;

  27.             select $FH{$1};
  28.             print $line;
  29.         }
  30.     }

  31.     #清理所有文件句柄
  32.     grep { close $FH{$_} } @group;
  33.     close READ;

  34.     select STDOUT;
  35. }

  36. COLLECT_DATA:
  37. {
  38.     my $RESULT;
  39.     my $TempFH;
  40.     open $RESULT, ">:raw", $DST or die "$!";

  41.     #按出现的次数排列出优先顺序
  42.     my @rank = sort_byValue(\%letter);

  43.     for my $name ( @rank )
  44.     {
  45.         print "Reading F$name.txt ... \n";
  46.         open $TempFH, "<:raw", "$wd/T$name.txt" or die "$!";
  47.         while (my $line = <$TempFH>)
  48.         {   
  49.             print $RESULT $line;
  50.         }
  51.         close $TempFH;
  52.     }

  53.     print "Please check $DST\n";
  54. }

  55. sub sort_byValue
  56. {
  57.     my $ref = shift;
  58.     my @arr;
  59.     @arr = reverse sort map { $ref->{$_} .",". $_  } keys %$ref;

  60.     my ($char, $times);
  61.     for (@arr)
  62.     {
  63.         ($times, $char) = split(",", $_);
  64.         print "char: $char, times: $times\n";
  65.     }

  66.     return (map { /,(.)$/; $_ = $1 } @arr);
  67. }

复制代码


作者: Windows19    时间: 2017-06-21 17:54
本帖最后由 Windows19 于 2017-06-21 18:01 编辑

回复 14# 523066680


执行脚本后返回
line 1: $'=info\r': command not found
line 2: code: command not found
line 3: $'2017-06\r': command not found
line 5: $'\r': command not found
line 6: use: command not found
line 7: use: command not found
line 7: $'\r': command not found
line 8: syntax error near unexpected token `('
line 8: `STDOUT->autoflush(1);



请问使用方法
作者: 523066680    时间: 2017-06-21 18:01
本帖最后由 523066680 于 2017-06-21 18:33 编辑

回复 15# Windows19

更新了,在开头 $SRC 和 $DST 设置读入的文件名和生成的文件名。

这个问题你需要在开头加上
#!/usr/bin/perl

18:32
呼,忘了检验结果,已更改错误的地方。

作者: sunzhiguolu    时间: 2017-06-21 18:24
别忘了 打赏!!!
作者: Windows19    时间: 2017-06-21 18:36
回复 17# sunzhiguolu

Can solve the problem
No problem

作者: sunzhiguolu    时间: 2017-06-21 18:41
本帖最后由 sunzhiguolu 于 2017-06-21 18:45 编辑

回复 16# 523066680
大神的功力果然是非同凡响,我是小白。
有几个问题向大神请教,还请帮忙指点,谢谢。
  1. use IO::Handle;
复制代码
代码中没见到用到该模块中的方法呀。

  1. STDOUT->autoflush(1);
复制代码
这个函数是个啥意思。

  1. ANALYSE_AND_EXPORT:
  2. {
  3.     ...
  4. }
复制代码
这是什么结构,代码从何处开始执行? 看的有点晕菜了。。。



作者: sunzhiguolu    时间: 2017-06-21 18:44
回复 18# Windows19
打赏啊 quanpai523066680。


作者: 523066680    时间: 2017-06-21 18:44
本帖最后由 523066680 于 2017-06-21 18:45 编辑

呼,我都忘了Windows保存的文件名不分大小写……

写的急促了,有点bug,再改改。

作者: Windows19    时间: 2017-06-21 18:50
回复 14# 523066680
谢谢
测试确实能搞动超大文件  而且效率超快
但产生有几个问题

不同文件测试, 有时候行数会少  但有时候行数会多1倍  (不知道原因了)

在统计字母串上不太准确  排序结果不对  (要精确匹配字母串,要分大小写)


如果能同时统计字母串 数字串 排序 那实在太好了

谢谢老师帮忙再改进

作者: 523066680    时间: 2017-06-21 18:56
回复 22# Windows19

数字是不是要另外导出一个文件的?

作者: Windows19    时间: 2017-06-21 18:57
回复 21# 523066680
谢谢老师

改好继续打赏

作者: Windows19    时间: 2017-06-21 18:59
回复 23# 523066680

全部一个文件就行  精确匹配字母串  数字串后     从多到小排序

作者: 523066680    时间: 2017-06-21 19:03
回复 25# Windows19

问题是,如果放一个文件,比如
1abcdef

1算一个,a算一个
结果中不就得放两次了么?

作者: Windows19    时间: 2017-06-21 19:13
回复 26# 523066680



像1abcdef


如果1出现333次abcdef又出现333次

会放2次
确实这种情况 好像不太好解决
但是应该有办法能决吧?

不急  慢慢想到办法再解决也行







作者: sunzhiguolu    时间: 2017-06-21 19:18
本帖最后由 sunzhiguolu 于 2017-06-21 19:19 编辑

回复 22# Windows19
每次看到你发帖,其实我都有点小激动。
但是,我一般都不太爱回复你的帖子内容,除非内容相对简单一些。

原因为何? 不知道你搞哪方面工作的,你的问题总感觉是将问题先抛砖引玉一下,随着回帖 将你的问题真正展开后 发现每个问题都是 玫瑰带刺 啊!
本人不才,没有那个水平。还是那句话,能将你的问题 成功解决 并保持 相对的效率 的话 一定是大牛


作者: Windows19    时间: 2017-06-21 19:19
回复 28# sunzhiguolu

谢谢老师指引
作者: 523066680    时间: 2017-06-21 19:23
更新,先处理a-zA-Z

  1. =info
  2.     Code by 523066680
  3.     2017-06 V2.0

  4.     Bug1 忘了windows文件名不分大小写,"Ta.txt" == "TA.txt",改为用ASCII码
  5.     Bug2 数值排序,而不是字符串排序 -- 例如:"9" 应小于 "21"
  6. =cut

  7. #!/usr/bin/perl
  8. use strict;
  9. use IO::Handle;
  10. STDOUT->autoflush(1);

  11. our $SRC = "A.txt";
  12. our $DST = "Final.txt";
  13. our %letter;
  14. our @group = map { ord($_) } ('a'..'z', 'A'..'Z');
  15. our $wd = "./tempfolder";
  16. mkdir $wd if (not -e $wd);

  17. ANALYSE_AND_EXPORT:
  18. {
  19.     my %FH;

  20.     #提前准备多个文件句柄
  21.     grep { open $FH{$_}, ">:raw", "$wd/T${_}.txt" or die "$!" } @group;

  22.     open READ, "<:raw", $SRC or die "$!";
  23.     while ( my $line = <READ> )
  24.     {
  25.         next if ( $line=~/^\r?\n$/ );

  26.         if ($line=~/([a-zA-Z])/)
  27.         {
  28.             $letter{$1} = 0 if ( not exists $letter{$1} );
  29.             $letter{$1}++;

  30.             select $FH{ord($1)};
  31.             print $line;
  32.         }
  33.     }

  34.     #清理所有文件句柄
  35.     grep { close $FH{$_} } @group;
  36.     close READ;

  37.     select STDOUT;
  38. }

  39. COLLECT_DATA:
  40. {
  41.     my $RESULT;
  42.     my $TempFH;
  43.     open $RESULT, ">:raw", $DST or die "$!";

  44.     #按出现的次数排列出优先顺序
  45.     my @rank = sort_byValue(\%letter);

  46.     for my $name ( @rank )
  47.     {
  48.         print "Reading F$name.txt ... \n";
  49.         open $TempFH, "<:raw", "$wd/T$name.txt" or die "$!";
  50.         while (my $line = <$TempFH>)
  51.         {   
  52.             print $RESULT $line;
  53.         }
  54.         close $TempFH;
  55.     }

  56.     print "Please check $DST\n";
  57. }

  58. sub sort_byValue
  59. {
  60.     my $ref = shift;
  61.     my @arr;

  62.     #不知道有没有绕弯路 =_=
  63.     @arr = reverse sort { "$a,$b," =~/-(\d+),.*-(\d+),/;  $1 <=> $2 }
  64.                     map {  $_ ."-". $ref->{$_} } keys %$ref;

  65.     my ($char, $times);
  66.     for (@arr)
  67.     {
  68.         ($char, $times) = split("-", $_);
  69.         print "char: $char, times: $times\n";
  70.     }

  71.     return ( map { /,(.)$/; $_ = ord($_) } @arr );
  72. }

复制代码

作者: sunzhiguolu    时间: 2017-06-21 19:30
回复 29# Windows19
我主要是也想看看
在 Perl 版, 难题面前谁能轻松应对。


作者: Windows19    时间: 2017-06-21 19:47
精确匹配字母串

sdfmslfmkwo340ifmks'/.'we.fds'.f'ws.fwf/'\./\sjfhiuesrtewtfrhfkjsyf/'\\/\

精确匹数字符串
/'\;.;''\.\. \/'.\.''\3156855556887945655564\';\.;\'./\



不是模湖匹配


作者: Windows19    时间: 2017-06-21 20:16
回复 30# 523066680

执行脚本后,行数少了3分1
估计同时统计字母串,数字串会引起冲突
就写统计字母串排序算了

如果想统计数字串排序,提供一个可以改成数字串排序就行了

作者: sunzhiguolu    时间: 2017-06-21 20:35
回复 33# Windows19
将你的文件 具有代表性的内容贴出一小部分。
方便进行测试,也方便后面大神解答。


作者: 523066680    时间: 2017-06-21 20:51
本帖最后由 523066680 于 2017-06-21 20:57 编辑

对于精确匹配的部分,

这里有多个部分,应该分别统计,还是以最长的一段为代表?
sdfmslfmkwo340ifmks'/.'we.fds'.f'ws.fwf/'\./\sjfhiuesrtewtfrhfkjsyf/'\\/\


-
如果数字串和字母串统计排列后,都存在一个文件中,数字串和字母串
应该按出现的次数统一排列?
abc  (100次 (省略细节
123  (99次
def   (50次
456  (20次

还是分字母串和数字串,分类排列?
abc  (100次
def   (50次
-
123  (99次
456  (20次


-
丢失1/3,是比原来的A.txt 小了一块吗?也许是有很多只有数字的行被排除了。我只考虑了含有字母的行。

作者: Windows19    时间: 2017-06-21 21:00
本帖最后由 Windows19 于 2017-06-21 21:09 编辑

回复 35# 523066680

1 应该分别统计   对的

2 应该按出现的次数统一排列   对的
abc  (100次 (省略细节
123  (99次
def   (50次
456  (20次





这样理解对的


3 我检查后真的有很多只有数字的行被排除了


还有符号行都被排除了
所以少了3/1





作者: Windows19    时间: 2017-06-21 21:03
本帖最后由 Windows19 于 2017-06-21 21:07 编辑

回复 30# 523066680

另外我测试发现   如果行中1个字母都没有    竞然是不会输出   所以和原文件行数不对原因   所以少了3/1
作者: 523066680    时间: 2017-06-21 21:23
sunzhiguolu 发表于 2017-06-21 18:41
回复 16# 523066680
大神的功力果然是非同凡响,我是小白。
有几个问题向大神请教,还请帮忙指点,谢谢。 ...

这个模块 IO::Handle 是为了开启自动刷新缓冲区,也就是为了使用:
STDOUT->autoflush(1);

有些Perl终端,在print 的时候输出顺序和预想的不一样,比如我 for (1..3) { print $_,"\n" },有可能输出显示是
3
1
2
开了自动刷新缓冲就没这个问题


    ANALYSE_AND_EXPORT:
    {
        ...
    }

这个 ANALYSE_AND_EXPORT: 和 { } 可以去掉,只留下中间代码部分一样可以运行。
我只是不想代码看起来一大坨,用{ } 将代码分段括起来,再加上一个标签让其看起来像个函数。

ANALYSE_AND_EXPORT: 是个标签,可以通过 goto 跳转的那种。


作者: sunzhiguolu    时间: 2017-06-21 21:53
回复 30# 523066680
  1. ANALYSE_AND_EXPORT:
  2. {
  3.     。。。
  4.     grep { open $FH{$_}, ">:raw", "$wd/T${_}.txt" or die "$!" } @group;
  5.     。。。
  6.     if ($line=~/([a-zA-Z])/)
  7. }
复制代码
":>raw" 这个方式我一直都搞不太明白和普通的 ">" 区别在哪里?
大神能否给个示例代码?

在 while 循环中
if ($line=~/([a-zA-Z])/) 针对每行的头一个字母字符进行统计? 其余的呢,能否解释下剩余部分如何处理?



作者: Windows19    时间: 2017-06-21 21:58
sunzhiguolu 发表于 2017-06-21 21:53
回复 30# 523066680
":>raw" 这个方式我一直都搞不太明白和普通的 ">" 区别在哪里?
大神能否给个示例代 ...

我以为是523066680老师上菜牌了

作者: sunzhiguolu    时间: 2017-06-21 22:01
本帖最后由 sunzhiguolu 于 2017-06-21 22:02 编辑

回复 40# Windows19
兄弟,你的问题有解决思路了吗?
可否用白话描述一下处理步骤,让吃瓜群众也明白一下。


作者: sunzhiguolu    时间: 2017-06-21 22:21
Windows19 发表于 2017-06-21 21:58
我以为是523066680老师上菜牌了

说实话 我不知你说这话是何意,难道你不想了解一下高手解决问题的思路。
难道对于你的问题,你已然了然于胸?
在 while 循环中
if ($line=~/([a-zA-Z])/) 针对每行的头一个字母字符进行统计? 其余的呢,能否解释下剩余部分如何处理?
你也太低估 523066680 大神的人品了。


作者: Windows19    时间: 2017-06-21 22:31
本帖最后由 Windows19 于 2017-06-21 22:37 编辑

回复 41# sunzhiguolu


按照35楼提出凝问

我猜523066680老师思路已经很清晰了      我想他已经明白了     
估计他正在想办法解决 字母串 数字串 因时统计有冲突问题   我相信他能解决的




还没看懂么?
其实就是统计出文本中所有字母串 数字串  重复次数   然后把这些行排序打印出来


作者: 523066680    时间: 2017-06-21 22:36
本帖最后由 523066680 于 2017-06-21 22:38 编辑

我觉得很烦躁,如果一段字符串的每一个不同部分都分别要统计
那最后堆到一个文件里肯定很难看的。如果是分别生成以关键字符串为名的txt,名字上在加上出现的次数,还直观一些。

如果每一行只取一段最长的关键字符串/关键数字串,则生成的冗余数据又能少一些。

老婆催我休息了(逃


作者: Windows19    时间: 2017-06-21 22:45
回复 44# 523066680

如果同时统计字母串,数字串会引起冲突

那就写分别统计文本内字母串算了        统计字母串是不会冲突的


另外
如果想统计数字串,提供一个可以改成数字串排序就行了








作者: 523066680    时间: 2017-06-21 22:47
回复 45# Windows19

其实我在想,如果生成HTML,关键字部分高亮,肯定很直观。
但是数据量大的话,浏览器也吃不消

作者: Windows19    时间: 2017-06-21 22:53
本帖最后由 Windows19 于 2017-06-21 22:55 编辑

回复 46# 523066680

就按照你35楼提出问题   我36搂回答你的  就按照这个思路写   只统计文本内字母串重复次数 然后排序打印   应该能实现
作者: 523066680    时间: 2017-06-21 23:02
本帖最后由 523066680 于 2017-06-21 23:05 编辑

以原帖中的数据为例

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

输出
f
65425855662efssaezsdfcsf//sff.sdf/'s;f]\sDed33dds3
65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33sdds1
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

sdf
65425855662efssaezsdfcsf//sff.sdf/'s;f]\sDed33dds3
65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33sdds1
efssaezsdfcsf//58969752sff.sdf/'s;f]\sDed33sds0
efssaezsdfcsf/        58969752/sff.sdf/'s;f]  \sDed33sdds5
65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33s00000000

efssaezsdfcsf
65425855662efssaezsdfcsf//sff.sdf/'s;f]\sDed33dds3
65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33sdds1
efssaezsdfcsf//58969752sff.sdf/'s;f]\sDed33sds0
efssaezsdfcsf/        58969752/sff.sdf/'s;f]  \sDed33sdds5
65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33s00000000

33
65425855662efssaezsdfcsf//sff.sdf/'s;f]\sDed33dds3
65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33sdds1
efssaezsdfcsf//58969752sff.sdf/'s;f]\sDed33sds0
efssaezsdfcsf/        58969752/sff.sdf/'s;f]  \sDed33sdds5
65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33s00000000

s
65425855662efssaezsdfcsf//sff.sdf/'s;f]\sDed33dds3
65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33sdds1
efssaezsdfcsf//58969752sff.sdf/'s;f]\sDed33sds0
efssaezsdfcsf/        58969752/sff.sdf/'s;f]  \sDed33sdds5
65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33s00000000

sDed
65425855662efssaezsdfcsf//sff.sdf/'s;f]\sDed33dds3
65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33sdds1
efssaezsdfcsf//58969752sff.sdf/'s;f]\sDed33sds0
efssaezsdfcsf/        58969752/sff.sdf/'s;f]  \sDed33sdds5
65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33s00000000

sff
65425855662efssaezsdfcsf//sff.sdf/'s;f]\sDed33dds3
65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33sdds1
efssaezsdfcsf//58969752sff.sdf/'s;f]\sDed33sds0
efssaezsdfcsf/        58969752/sff.sdf/'s;f]  \sDed33sdds5
65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33s00000000

65425855662
65425855662efssaezsdfcsf//sff.sdf/'s;f]\sDed33dds3
65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33sdds1
65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33s00000000
65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com

5
yjyjgwwwghfg56www g.tgjgcom445.5454.'55.4l5
efssaezsdfcsf/        58969752/sff.sdf/'s;f]  \sDed33sdds5
65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com

www
yjyjgwwwghfg56www g.tgjgcom445.5454.'55.4l5
65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com

58969752
efssaezsdfcsf//58969752sff.sdf/'s;f]\sDed33sds0
efssaezsdfcsf/        58969752/sff.sdf/'s;f]  \sDed33sdds5

sdds
65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33sdds1
efssaezsdfcsf/        58969752/sff.sdf/'s;f]  \sDed33sdds5

g
yjyjgwwwghfg56www g.tgjgcom445.5454.'55.4l5
65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com

dds
65425855662efssaezsdfcsf//sff.sdf/'s;f]\sDed33dds3

56
yjyjgwwwghfg56www g.tgjgcom445.5454.'55.4l5

fsfsf
65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com

l
yjyjgwwwghfg56www g.tgjgcom445.5454.'55.4l5

sds
efssaezsdfcsf//58969752sff.sdf/'s;f]\sDed33sds0

1
65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33sdds1

com
65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com

yjyjgwwwghfg
yjyjgwwwghfg56www g.tgjgcom445.5454.'55.4l5

445
yjyjgwwwghfg56www g.tgjgcom445.5454.'55.4l5

tgjgcom
yjyjgwwwghfg56www g.tgjgcom445.5454.'55.4l5

e
65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com

x
65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com

3
65425855662efssaezsdfcsf//sff.sdf/'s;f]\sDed33dds3

54
65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com

r
65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com

ftfr
65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com

55
yjyjgwwwghfg56www g.tgjgcom445.5454.'55.4l5

ty
65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com

efs
65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com

saezsdf
65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com

grytryg
65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com

t
65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com

00000000
65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33s00000000

4
yjyjgwwwghfg56www g.tgjgcom445.5454.'55.4l5

0
efssaezsdfcsf//58969752sff.sdf/'s;f]\sDed33sds0

5454
yjyjgwwwghfg56www g.tgjgcom445.5454.'55.4l5

6
65425855662efs\saezsdf][grytryg*f-x+f5g5ty'5t;54r]\5/e.,6ftfr//www.fsfsf.com




作者: Windows19    时间: 2017-06-21 23:25
本帖最后由 Windows19 于 2017-06-21 23:37 编辑

回复 48# 523066680
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



如果统计字母串   f是重复最多的  应该把有f行排前  然后s  然后sff    然后sdf  把这些最多的行排序打印出来就对了

      7 f
      6 s
      5 sff
      5 sdf
      5 sDed
      5 efssaezsdfcsf
      2 www
      2 sdds
      2 g
      1 yjyjgwwwghfg
      1 x
      1 ty
      1 tgjgcom
      1 t
      1 sds
      1 saezsdf
      1 r
      1 l
      1 grytryg
      1 ftfr
      1 fsfsf
      1 efs
      1 e
      1 dds
      1 com



作者: Windows19    时间: 2017-06-21 23:33
                  
作者: 523066680    时间: 2017-06-22 08:34
回复 49# Windows19

s 出现6次?我不信,请详细举出所在位置。

作者: Windows19    时间: 2017-06-22 09:01
回复 51# 523066680

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


确实是6次

作者: 523066680    时间: 2017-06-22 09:05
回复 52# Windows19

65425855662efssaezsdfcsf/        /sff.sdf/'s;f]  \sDed33s00000000

一行内两次算是2次吗?我以为一行内多次也计为1次,还特地做了判断

作者: Windows19    时间: 2017-06-22 09:06
如果能解决"会存在放2次以上问题"   那么字母串  数字串一起统计排序应该没问题
作者: Windows19    时间: 2017-06-22 09:21
回复 53# 523066680 如果算2次影响效率
那在一行内出现相同的算1次也可以




作者: Windows19    时间: 2017-06-22 09:23
记得删除临时产生文件
作者: Windows19    时间: 2017-06-22 10:50
523066680老师

测试30代码

排序次数不太准确

出现222次的行,会放在出现336次前面去

另外,他只适应有字母行,能否改改适应所有字符呢?

其他的没发现问题

如果太难,改正一下上面问题就算了,我将就用着

谢谢了

作者: 523066680    时间: 2017-06-22 11:43
本帖最后由 523066680 于 2017-06-22 11:47 编辑

回复 57# Windows19

30的代码早就不行了,只针对你化简的问题(仅以开头出现的字母作为统计依据),而且没考虑数字。
对了你测试到出错的地方,尽量把具体的数据片段提供一下啊。
要不提取几百M压缩后上传百度网盘?



作者: Windows19    时间: 2017-06-22 11:55
523066680 发表于 2017-06-22 11:43
回复 57# Windows19

30的代码早就不行了,只针对你化简的问题(仅以开头出现的字母作为统计依据),而 ...

我传给你QQ如何?
作者: 523066680    时间: 2017-06-22 12:00
回复 59# Windows19

1091993445

作者: Windows19    时间: 2017-06-22 12:24
回复 60# 523066680

3q加了
作者: 523066680    时间: 2017-06-22 21:23
本帖最后由 523066680 于 2017-06-23 09:25 编辑

新学了一个模块 - DB_File,不熟练。
优点:占用内存少
缺点:特别耗时

处理机制:参考63楼

  1. =info
  2.     Code by 523066680
  3.     2017-06
  4. =cut

  5. #!/usr/bin/perl
  6. use Fcntl;
  7. use DB_File;
  8. use IO::Handle;
  9. use Data::Dumper;
  10. use Time::HiRes qw/sleep/;
  11. STDOUT->autoflush(1);

  12. our $SRC = "D:/A.txt";
  13. our $DST = "D:/Final.txt";
  14. our $FH_SRC;
  15. our $FH_DST;
  16. our $DB_KEY    = "F:/keywords.dat";
  17. our $DB_LINE   = "F:/lines.dat";
  18. our $DB_OFFSET = "F:/line_offset.dat";
  19. our $DB_SORT   = "F:/sort.dat";

  20. our $fold = "D:/tempfolder_words";  #尽可能独立的目录名称

  21. our %keywords;
  22. our @lines;
  23. our @offset;   #保存每一行的索引位置+长度
  24. our %rank;     #每行的元素次数信息

  25. unlink $DB_KEY;
  26. unlink $DB_LINE;
  27. unlink $DB_OFFSET;
  28. unlink $DB_SORT;

  29. tie %keywords, "DB_File", $DB_KEY, O_WRONLY|O_CREAT, 0666, $DB_BTREE or die $!;
  30. tie @lines, "DB_File", $DB_LINE, O_WRONLY|O_CREAT, 0666, $DB_RECNO or die $!;
  31. tie @offset, "DB_File", $DB_OFFSET, O_WRONLY|O_CREAT, 0666, $DB_RECNO or die $!;

  32. # 排序函数设置
  33. $DB_BTREE->{'compare'} = \&Compare ;
  34. tie %rank, "DB_File", $DB_SORT, O_WRONLY|O_CREAT, 0666, $DB_BTREE or die $!;

  35. #our %rank;           #等级索引

  36. LOAD_DATA:
  37. {
  38.     print "Loading ... \n";
  39.     open $FH_SRC, "<:raw", $SRC or die $!;

  40.     my $filesize = -s $SRC;
  41.     my $curr = 0;
  42.     my $prev = 0;

  43.     my $time_a = time();
  44.     my $percent;

  45.     #每行的偏移量
  46.     my $offsetA = 0;
  47.     my $offsetB;
  48.     my @parts;

  49.     #单行的重复关键词判断
  50.     my %inline;

  51.     while ( my $line = <$FH_SRC>)
  52.     {
  53.         #next if ($line=~/^\s*\r?\n$/);  #排除空行
  54.         %inline = ();
  55.         @parts = $line =~/([a-zA-Z]+|[\d]+)/g;

  56.         #累积关键字出现的次数
  57.         for my $e (@parts)
  58.         {
  59.             if ( not exists $keywords{$e} ) { $keywords{$e} = 1    }
  60.             else { $keywords{$e}++ if (not exists $inline{$e}) }

  61.             $inline{$e} = 1;
  62.         }

  63.         #每行的关键字数据
  64.         push @lines, join(",", keys %inline);

  65.         #每行的偏移量和长度信息
  66.         $offsetB = tell( $FH_SRC );
  67.         push @offset, join(",", $offsetA, $offsetB - $offsetA);

  68.         #更新起点位置
  69.         $offsetA = tell( $FH_SRC );

  70.         $curr = $offsetA / $filesize * 100.0;
  71.         if ( ($curr - $prev) > 1.0  )
  72.         {
  73.             print ".";
  74.             $prev = $curr;
  75.         }
  76.         
  77.     }
  78.     print "\n";

  79.     close $FH_SRC;

  80.     printf "Time use: %s seconds\n", time()- $time_a;
  81. }

  82. ANALYSE_AND_SORT:
  83. {
  84.     my $time_a = time();
  85.     print "Sorting key of each line ... \n";

  86.     #利用 DB_File 机制排序
  87.     for my $idx ( 0 .. $#lines )
  88.     {
  89.         # key = 行号,每个关键字的次数(从大到小)
  90.         $key = join ( ",", $idx,
  91.                     reverse sort { $a <=> $b } map { $keywords{$_} } split(",", $lines[$idx])
  92.                 );

  93.         # value = 该行的位置索引
  94.         $rank{$key} = $offset[$idx];
  95.     }

  96.     printf "Time use: %s seconds\n", time()- $time_a;
  97. }

  98. FINAL_OUTPUT:
  99. {
  100.     print "Almost finish\n";

  101.     my $time_a = time();
  102.     my ($k, $v);
  103.     my ($site, $len);
  104.     my $buff;

  105.     open $FH_SRC, "<:raw", $SRC or die $!;
  106.     open $FH_DST, ">:raw", $DST or die $!;

  107.     while ( ($k, $v) = each %rank )
  108.     {
  109.         ($site, $len) = split(",", $v);
  110.         seek($FH_SRC, $site, 0);
  111.         read($FH_SRC, $buff, $len);
  112.         $buff=~s/\r?\n$//;
  113.         print $FH_DST $buff,"\r\n";
  114.     }

  115.     close $FH_SRC;
  116.     close $FH_DST;

  117.     printf "Time use: %s seconds\n", time() - $time_a;

  118.     untie %keywords;
  119.     untie @lines;
  120.     untie @offset;
  121.     untie %rank;
  122. }

  123. sub Compare
  124. {
  125.     my ($ka, $kb) = @_ ;
  126.     my @ar = split(",", $ka);
  127.     my @br = split(",", $kb);
  128.     my $i = 1;

  129.     while ( ($ar[$i] <=> $br[$i] ) == 0
  130.             and $#ar > $i
  131.             and $#br > $i
  132.             #and $i < 3
  133.         ) {  $i++;  }
  134.    
  135.     $br[$i] <=> $ar[$i]  ||  $#br <=> $#ar || $br[0] <=> $ar[0];
  136.     #如果最后一位相同,比较元素数量;如果数量相同,按下标大小排列
  137. }

  138. __END__
复制代码

作者: 523066680    时间: 2017-06-22 23:12
本帖最后由 523066680 于 2017-06-23 15:04 编辑

以原贴的段落为例,
[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



作者: Windows19    时间: 2017-06-23 08:57
回复 62# 523066680

嗯嗯  测试后基本正确  就是效率有点慢,  100m耗时59分钟左右  如果要处理超过100g  估计也得1个月左右
能否加快一点时间?  比如 使用多线程处理  现在好像只用1个cpu来处理   使用多线程处理 效率会不会再快些?

如果能优化效率就太好了

辛苦了  再赏



测试文件97.0 MB耗时
$ perl 123
Loading ...
Time: 538 seconds
Sorting key of each line ...
Almost finish
Time: 1391 seconds




麻烦在有空闲时间抽空关注一下看看能不能再改进一下  谢谢


作者: 523066680    时间: 2017-06-23 09:27
本帖最后由 523066680 于 2017-06-23 10:08 编辑

回复 64# Windows19

是在服务器跑吗,如果是100G,会生成大约 600G 的临时文件。
如果每行只取一个频率最高的词作为代表 (其他低频率不考虑,可以加快)

比如这两行的每个关键字的频率列表:
[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

如果只对比开头,都是6次,这两项数据并排,后面的不再对比。

-

不懂多线程 -_-

作者: Windows19    时间: 2017-06-23 10:44
523066680 发表于 2017-06-23 09:27
回复 64# Windows19

是在服务器跑吗,如果是100G,会生成大约 600G 的临时文件。

嗯嗯,ok  还是老师你的意路灵活,

作者: hztj2005    时间: 2017-06-23 22:36
这是个大工程,向523066680学习下。
作者: csccyab    时间: 2019-01-31 16:33
本帖最后由 csccyab 于 2019-01-31 16:37 编辑


Python

  1. import re, collections, operator

  2. str_dict = collections.defaultdict(list)
  3. line_number = 0
  4. lines_printed = []

  5. f = open("1.txt")
  6. for line in f:
  7.         line_number += 1
  8.         for str in re.findall('[a-zA-Z]', line):
  9.                 str_dict[str].append(line_number)

  10. str_dict_sorted = { i: str_dict[i] for i in sorted(str_dict, key = lambda k: len(str_dict[k]), reverse=True) }
  11. f.close()

  12. for the_key, the_value in str_dict_sorted.items():
  13.         for i in the_key:
  14.                 for j in str_dict_sorted[i]:
  15.                         with open("1.txt") as file:
  16.                                 for ln, l in enumerate(file):
  17.                                         if ln+1 == j and ln not in lines_printed:
  18.                                                 print (l.strip())
  19.                                                 lines_printed.append(ln)
复制代码





欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2