免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 61612 | 回复: 14
打印 上一主题 下一主题

统计a文件中某个元素在b文件出现的次数 [复制链接]

论坛徽章:
1
羊年新春福章
日期:2015-04-28 20:40:58
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-08-13 18:10 |只看该作者 |倒序浏览
各位大神:
如果a.txt第一列与b.txt第二列相同,统计b.txt的第三列数与第四列数之间出现的A,B或C(a.txt的第三列)的次数。如果a.txt的第二列在b.txt的第三列与第四列之间,那么就把a.txt的第四列出现的次数加1。结果如下:
len            start  end  A  B  C
len_1        01        330        401  1   3   0
len_2        01        432        452  0   1   1
len_3        01        500        600  0  3    4

a.txt
01        333        A
01        369        B
01        387        B
01        400        B
01        416        B
01        450        C
01        455        B
01        466        B
01        468        B
01        471        C
01        504        B
01        506        B
01        508        C
01        522        C
01        523        B
01        577        C
01        600        C
01        607        A
02        609        B
02        645        B
.....
......

b.txt
len_1        01        330        401
len_2        01        432        452
len_3        01        500        600
......
......

谢谢各位大神!

论坛徽章:
1
羊年新春福章
日期:2015-04-28 20:40:58
2 [报告]
发表于 2016-08-13 18:52 |只看该作者
本帖最后由 清泉一边 于 2016-08-13 18:52 编辑
  1. #!/usr/bin/perl -w
  2. use strict;
  3. open (IN1,"C:\\Users\\lenovo\\Desktop\\a.txt") || die "no1";
  4. open (IN2,"C:\\Users\\lenovo\\Desktop\\b.txt")|| die "no2";
  5. print "len start  end  A  B  C";
  6. while (my $line = <IN1>){
  7. chomp $line;
  8. my @r = split /\t/,$line;
  9. my $a = 0;
  10. my $b = 0;
  11. my $c = 0;
  12.         while (<IN2>){
  13.         chomp;
  14.         my @s = split /\t/,$_;
  15.                         if ($s[0] eq $r[1] &&  $s[1]>=$r[2] && $s[1]<=$r[3] && $s[2] eq "A"){
  16.                            $a ++;
  17.                            }
  18.                  elsif ($s[0] eq $r[1] && $s[1]>=$r[2] && $s[1]<=$r[3] && $s[2] eq "B"){
  19.                            $b ++;
  20.                            }
  21.                  elsif ($s[0] eq $r[1] && $s[1]>=$r[2] && $s[1]<=$r[3] && $s[2] eq "C"){
  22.                            $c ++;
  23.                            }
  24.         }
  25. print "$line\t$a\t$b\t$c\n";
  26. }

  27. print "over";
复制代码
不知道错哪儿啦?哪位大神给看看~回复 1# 清泉一边


   

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
3 [报告]
发表于 2016-08-13 19:10 |只看该作者
有个地方没看明白, 请解释下:
len_2        01        432        452  0   1   1, 估计跟你的问题描述的后半段有关系. 如果a.txt的第二列在b.txt的第三列与第四列之间,那么就把a.txt的第四列出现的次数加1。

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
4 [报告]
发表于 2016-08-13 19:20 |只看该作者
总感觉你的 @r, @s 进行范围比较时用的索引值与你提供的示例文本的对应关系不太对.

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
5 [报告]
发表于 2016-08-13 20:21 |只看该作者
问题 3 处:
1.> 文件句柄 IN2 在外, IN1 在内
2.> 每次进入内循环的 while 之前, 重新打开一下 IN1 句柄
3.> 数组 @r, @s 与元素之间的对应关系

论坛徽章:
6
丑牛
日期:2014-03-21 15:42:04子鼠
日期:2014-04-12 11:50:17处女座
日期:2014-09-01 09:25:1115-16赛季CBA联赛之吉林
日期:2015-12-22 14:01:5215-16赛季CBA联赛之广东
日期:2016-03-08 18:49:422016科比退役纪念章
日期:2016-07-06 12:19:55
6 [报告]
发表于 2016-08-13 20:53 |只看该作者
没有具体看你的对比的逻辑。。。
目测open IN2应该在while里面吧,如:
  1. #!/usr/bin/perl -w
  2. use strict;
  3. open (IN1,"C:\\Users\\lenovo\\Desktop\\a.txt") || die "no1";
  4. print "len start  end  A  B  C";
  5. while (my $line = <IN1>){
  6. chomp $line;
  7. my @r = split /\t/,$line;
  8. my $a = 0;
  9. my $b = 0;
  10. my $c = 0;
  11. open (IN2,"C:\\Users\\lenovo\\Desktop\\b.txt")|| die "no2";
  12.         while (<IN2>){
  13.         chomp;
  14.         my @s = split /\t/,$_;
  15.                         if ($s[0] eq $r[1] &&  $s[1]>=$r[2] && $s[1]<=$r[3] && $s[2] eq "A"){
  16.                            $a ++;
  17.                            }
  18.                  elsif ($s[0] eq $r[1] && $s[1]>=$r[2] && $s[1]<=$r[3] && $s[2] eq "B"){
  19.                            $b ++;
  20.                            }
  21.                  elsif ($s[0] eq $r[1] && $s[1]>=$r[2] && $s[1]<=$r[3] && $s[2] eq "C"){
  22.                            $c ++;
  23.                            }
  24.         }
  25. print "$line\t$a\t$b\t$c\n";
  26. }

  27. print "over";
复制代码

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
7 [报告]
发表于 2016-08-13 21:36 |只看该作者
stanley_tam 发表于 2016-08-13 20:53
没有具体看你的对比的逻辑。。。
目测open IN2应该在while里面吧,如:

目测好像也需要点依据吧,

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
8 [报告]
发表于 2016-08-13 21:43 |只看该作者
本帖最后由 sunzhiguolu 于 2016-08-13 21:47 编辑

来一个:
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use Tie::File;

  5. open (my $fhR, '<', './b');
  6. tie (my @aFa, 'Tie::File', './a');
  7. while (defined (local $_ = <$fhR>)){
  8.     my (@aB, @aA) = split;
  9.     my %hCnt = map {$_, 0} 'A' .. 'C';
  10.     foreach (@aFa){
  11.         @aA = split;
  12.         $hCnt{$aA[-1]}++ if ($aB[1] eq $aA[0] and $aB[2] <= $aA[1] and $aA[1] <= $aB[-1]);
  13.     }
  14.     print join ("\t", @aB, @hCnt{'A', 'B', 'C'}), "\n";
  15. }
  16. close ($fhR);
复制代码
len_1   01      330     401     1       3       0
len_2   01      432     452     0       0       1
len_3   01      500     600     0       3       4

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
9 [报告]
发表于 2016-08-13 22:00 |只看该作者
本帖最后由 sunzhiguolu 于 2016-08-13 22:06 编辑

再来,
  1. #!/usr/bin/perl -w
  2. use strict;

  3. my (@aChars, %hMap) = ('A' .. 'C');
  4. open (my $FHa, '<', './a');
  5. map {my @aT = split; push (@{$hMap{$aT[0]}}, [@aT])} <$FHa>;
  6. close ($FHa);
  7. open (my $FHb, '<', './b');
  8. while (defined (local $_ = <$FHb>)){
  9.     my @aB = split;
  10.     my %hCnt = map {$_, 0} @aChars;
  11.     foreach (@{$hMap{$aB[1]}}){
  12.         $hCnt{$_->[-1]}++ if ($_->[1] >= $aB[2] and $_->[1] <= $aB[-1]);
  13.     }
  14.     print join ("\t", @aB, @hCnt{@aChars}), "\n";
  15. }
  16. close ($FHb);
复制代码

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
10 [报告]
发表于 2016-08-14 12:06 |只看该作者
本帖最后由 jason680 于 2016-08-14 12:37 编辑

$ perl get_len.pl
        len        start        end        A        B        C
len_1        01        330        401        1        3        0
len_2        01        432        452        0        0        1
len_3        01        500        600        0        3        4

$ cat get_len.pl
use strict;
use warnings;

my $sFa = "a.txt";
my $sFb = "b.txt";

open(my $FHa, "<", $sFa) or die "can't open $sFa\n";
open(my $FHb, "<", $sFb) or die "can't open $sFb\n";

sub get_len{
   my($FH) = @_;
   $_ = <$FH>;
   s/\s*$//;
   return(split);
}

my $sCnt = 0;
my ($sNum_a, $sVal, $sKey) = (0,0,"");  
print join("\t", " ", qw/ len start end A B C/), "\n";
while(<$FHb>){
  chomp;  
  my($sLen, $sNum, $sStart, $sEnd) = split;
  
  my %hCnt=('A' => 0, 'B' => 0, 'C' => 0);
  while($sNum > $sNum_a or $sNum == $sNum_a && $sVal <= $sEnd ){
     ++$hCnt{$sKey} if($sNum==$sNum_a && $sStart <= $sVal && $sVal <= $sEnd);
     last if eof $FHa;
     ($sNum_a, $sVal, $sKey) = get_len($FHa);  
  }
  print join("\t", $sLen, $sNum, $sStart, $sEnd, @hCnt{qw/A B C/}),"\n";
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP