哈希表解决提取reads问题

问题描述,有两个文件,一个是基因和其相对应所包含的readsID以及是正反向测序是否都要的标识。


格式如下:Tea_CCG055929.1&FCC55J8ACXX:8:1101:6302:2021#TAGCTTAT/1&A


基因名&reads名&标识。如果A则正反都要,如果S则只要一条。

另一个则是reads文件标准fq格式。

依据关键字文件找出对应的reads序列存入相应基因名字建立的文件中。

reads文件大约13G,关键字文件大约2G。如果用平常循环比对,耗时将非常长。时间复杂度也为O(mn),若采用哈希表存储结构先将关键字文件存储进去,将reads文件一一比对,时间复杂度将降低到O(n)。


哈希表存储结构关键是哈希函数的构造,用perl写了一个统计关键字文件有多少行以及最后一个数字最大为多少(如例子格式最后一个数字为2021);最终统计出总共有35741312条数据,最大值为100685 。 装载因子采用0.7 所以哈希函数为 hash(KEY)=KEY×500; 存储数组为0-50342500。冲突解决方式为开放地址法,最终地址为H=hash(KEY)+di; 

代码如下:

#/usr/bin/perl -w
use strict;
my $myReads="read1.fq";#reads文件
my $myFileAdd=".fastq1";
my $outDir="gene/";#输出目录
my $mySmalt="example.txt";#smalt结果文件

my $MAXSIZE=50342500;
my $myAmplify=500;
my @array;
my $i=0;
my $mybeginAdd=0;
my $GeneName="";
my $ReadsName="";
my $myFlag="";
my $outFlag=0;
my $countNum=0;
my $myResult="";
for($i=0;$i<=$MAXSIZE;$i++){
   $array[$i]="END";
}
open(myFile,$mySmalt)||die("connot open file 1");
while(my $myLine=<myFile>){
  if($myLine=~/(\S+)\&(\S+)\&(\S+)/){
          $ReadsName=$2;
          if($ReadsName=~/(\S+)\:(\S+):(\S+):(\S+):(\S+)\#/){
         $mybeginAdd=$5*$myAmplify;

            $mybeginAdd=&myHash($mybeginAdd);

             $array[$mybeginAdd]=$myLine;

           }
           }

}
close(myFile);

open(myFile,$myReads)||die("connot open file 2");
while(my $myLine=<myFile>){
chomp($myLine);
if($myLine=~/@/){
     if($myLine=~/\@(\S+)\:(\S+):(\S+):(\S+):(\S+)\#/){
         $mybeginAdd=$5*$myAmplify;

         if($mybeginAdd>$MAXSIZE){
             next;
         }
            while(!($array[$mybeginAdd] eq "END")){

            if($array[$mybeginAdd]=~/(\S+)\&(\S+)\&(\S+)/){
              $GeneName=$1;
              $ReadsName=$2;
              $myFlag=$3;
              if($myFlag eq "A"){
                 if($ReadsName=~/(\S+)\/(\S+)/){
                    $ReadsName=$1;

                 }

              }
                               if($myLine=~/$ReadsName/){

                               $outFlag=1;
                               $countNum=0;
                               open(OUTFILE,">>".$outDir.$GeneName.$myFileAdd)||die("cannot open outfile");
                               print OUTFILE $myLine."\n";
                               close(OUTFILE);
                               last;
                               }

              }

              $mybeginAdd++;
              if($mybeginAdd>$MAXSIZE){
                         $mybeginAdd=$mybeginAdd%$MAXSIZE;
                      }
            }

           }
     }
     elsif($outFlag==1){
        if($countNum==2){
          $myResult.=$myLine."\n";
          open(OUTFILE,">>".$outDir.$GeneName.$myFileAdd)||die("cannot open outfile");
                               print OUTFILE $myResult;
                               close(OUTFILE);
                               $outFlag=0;
                               $myResult="";
        }
        else
        {
          $myResult.=$myLine."\n";
        }
        $countNum++;

     }
}
close(myFile);

sub myHash{
                 my ($myAdd) =@_;

                 $myAdd=$myAdd+0;

                 while(!($array[$myAdd] eq "END")){
                      $myAdd++;
                      if($myAdd>$MAXSIZE){

                         $myAdd=$myAdd%$MAXSIZE;
                      }

                 }
                   return ($myAdd);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值