免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
12下一頁
最近訪問板塊 發新帖
查看: 60644 | 回復: 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
   日韩综合区视频第一页导航,无码JK粉嫩小泬在线观看,午夜精品A片一区二区三区,日日躁夜夜躁狠狠躁麻豆,大胆国模,免费观看无遮挡www的网站