免费注册 查看新帖 |

Chinaunix

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

急急急!提取最长序列 [复制链接]

论坛徽章:
2
15-16赛季CBA联赛之山西
日期:2016-03-03 17:51:32CU十四周年纪念徽章
日期:2016-03-21 18:45:39
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-09-28 13:42 |只看该作者 |倒序浏览
本帖最后由 赛萌 于 2015-09-28 14:30 编辑

>EM.1.1 EM.1 LK029911.1 +
CTGTCAATCCCGCACATTAAAGCATCTCTCTCCCCTTGCCTATTTTCTCGCCCCTTCCccatcctccttctctctcgctctctcctaGCATAGCTCCAAGCGCGAGGAACA
>EM.1.2 EM.1 LK029911.1 +
TCCTTTTAAGTACTGCAAACATACCTGGCGGCTTAAGCTTGCAGTATAATGTCAAGTGCTTCCCTACCACTTATTGCTTATAATTGTGATCACCCGTCAAATTGGTCGTTCTTGGAATATAGGCTCTTACTTTTAGAGCATGGTTATTTAAACAGGGGGACGAAAATCCCTCTTTGCTCAATGTAAGTCAGCTAGTTGTACTTACGTTTTGAACTCCACGTCCACACTGGAACAGCATTCGCTATGGACTGTGTCACACGACAAGCAGGTATGTTCATTT
>EM.1.3 EM.1 LK029911.1 +
CTGTCAATCCCGCACATTAAAGCATCTCTCTCCCCTTGCCTATTTTCTCGCCCCTTCCccatcctccttctctctcgctc
很多上面的这些个序列,要求是 EM.1相同的情况下,EM.1.1、EM.1.2、EM.1.3下面对的序列哪个长就把那个提取出来,像这个结果就要是
> EM.1
TCCTTTTAAGTACTGCAAACATACCTGGCGGCTTAAGCTTGCAGTATAATGTCAAGTGCTTCCCTACCACTTATTGCTTATAATTGTGATCACCCGTCAAATTGGTCGTTCTTGGAATATAGGCTCTTACTTTTAGAGCATGGTTATTTAAACAGGGGGACGAAAATCCCTCTTTGCTCAATGTAAGTCAGCTAGTTGTACTTACGTTTTGAACTCCACGTCCACACTGGAACAGCATTCGCTATGGACTGTGTCACACGACAAGCAGGTATGTTCATTT
下面是我写的程序,写的有问题,我自己看不出,因为得出的结果有25个是重复的,就是提出来有25个是提取了两次
#!perl
use strict;
use warnings;
use Data::Dumper;

die "usage $0 input output" unless @ARGV==2;
open IN,$ARGV[0];
my $zn;
my $n;
my %seq;
while(<IN>){
        if(s/^>//){               
                my @its=split;
                $n=$its[0];
                $zn=$its[1];
        }else{
                chomp;
                $seq{$zn}{$n}.=$_;               
        }       
}
close IN;
#print Dumper(%seq),"\n";
open OUT,">","$ARGV[1]";
my %seq1;
my %seq2;
my $seq;
foreach my  $zw (keys %seq){
#        my $seq=$seq{$zw};
        my @length;
        foreach my $w (keys %{$seq{$zw}}){
                $seq=$seq{$zw}{$w};
#                $seq="\U$seq";
                my $length=length($seq);
                push @length,$length;
                $seq1{$zw}{$w}{$length}{$seq}=1;
        }
#        print Dumper(%seq1);
        my $longest=$length[-1];
        foreach(@length){
                $longest=$_ if $_ > $longest;
        }
       
    foreach my $w (keys %{$seq1{$zw}}){
            foreach (keys %{$seq1{$zw}{$w}}){
                    if(exists $seq1{$zw}{$w}{$longest}){
                            my $seqs=Dumper(keys %{$seq1{$zw}{$w}{$longest}});
                            my @seqs=keys %{$seq1{$zw}{$w}{$longest}};
#                            print "@seqs\n";
                            print OUT ">$zw\n@seqs\n";
                    }                                      
            }           
    }      
}   

论坛徽章:
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
2 [报告]
发表于 2015-09-28 15:27 |只看该作者
本帖最后由 sunzhiguolu 于 2015-09-28 17:32 编辑

回复 1# 赛萌
您的代码好多地方, 我还没有接触到. 所以不能为您指出问题, 抱歉.  
在没有更好的解决方案前, 可以试下我这个, 等有了更好的方法再更换好了! (笨方法)
  1. #!/usr/bin/perl
  2. use 5.010;
  3. use strict;
  4. use warnings;

  5. #函数 set_or_get_last_id 用来存放或获取上一次的 $id 的值
  6. sub set_or_get_last_id{
  7.         state $last_id;
  8.         $last_id = shift if (@_);
  9.         $last_id;
  10. }

  11. #哈希变量 %keys_name, %keys_value 并行存储 ($id, $name) 及 ($id, $max_long_str)
  12. my (%keys_name, %keys_value, $max_long_str);
  13. while(<>){
  14.         my ($name, $id);
  15.         chomp;
  16.         my @a_line = split /\s+/;
  17.         if (m/^>/){
  18.                 ($name, $id) = ($a_line[0], $a_line[1]);
  19.                 if (!(exists $keys_name{$id})){
  20.                         $name =~ s/\.[0-9]+$//;    #加入这句
  21.                         $keys_name{$id} = $name;
  22.                         $keys_value{$id} = "";
  23.                         set_or_get_last_id($id);
  24.                 }
  25.         }else{
  26.                 my $last_id = set_or_get_last_id();
  27.                 $max_long_str = $keys_value{$last_id};
  28.                 my $current_str = $a_line[0];
  29.                 if (length($current_str) > length($max_long_str)){
  30.                         $keys_value{$last_id} = $current_str;
  31.                 }
  32.         }
  33. }

  34. foreach (keys %keys_name){
  35.         print "$keys_name{$_}\n$keys_value{$_}\n";
  36. }
复制代码

论坛徽章:
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 [报告]
发表于 2015-09-28 15:38 |只看该作者
本帖最后由 sunzhiguolu 于 2015-09-28 17:40 编辑

    另外, 借此机会我也向大家请教一个问题. 我希望将 while 循环封装成一个函数, 怎么将两个哈希变量返回给调用方. 像下面的这种方式吗?
  1. sub abc{
  2.    ...
  3.    (\%keys_name, \%keys_value);
  4. }
复制代码
这种方法返回的列表, 随着方法的结束数据是否会受到影响? 还是有更好的方法?
还请大家给予帮助及指点... 多谢大家...

论坛徽章:
2
15-16赛季CBA联赛之山西
日期:2016-03-03 17:51:32CU十四周年纪念徽章
日期:2016-03-21 18:45:39
4 [报告]
发表于 2015-09-28 15:52 |只看该作者
回复 2# sunzhiguolu


   艾,你写的我也看不懂

论坛徽章:
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 [报告]
发表于 2015-09-28 15:56 |只看该作者
本帖最后由 sunzhiguolu 于 2015-09-28 16:05 编辑

回复 4# 赛萌
比方说? 具体一点... 另外, 代码试过了吗? (我们是希望探讨代码的内容吗? 还是先测试下代码能否得到您的期望的结果.)
   

论坛徽章:
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
6 [报告]
发表于 2015-09-28 16:01 |只看该作者
本帖最后由 jason680 于 2015-09-28 16:04 编辑

回复 1# 赛萌

$ perl max_length.pl
> EM.1
TCCTTTTAAGTACTGCAAACATACCTGGCGGCTTAAGCTTGCAGTATAATGTCAAGTGCTTCCCTACCACTTATTGCTTATAATTGTGATCACCCGTCAAATTGGTCGTTCTTGGAATATAGGCTCTTACTTTTAGAGCATGGTTATTTAAACAGGGGGACGAAAATCCCTCTTTGCTCAATGTAAGTCAGCTAGTTGTACTTACGTTTTGAACTCCACGTCCACACTGGAACAGCATTCGCTATGGACTGTGTCACACGACAAGCAGGTATGTTCATTT

$ cat max_length.pl
use strict;
use warnings;

my $sEM  = "";
my $sSeq = "";
my %hSeq;

sub check_length{
  my ($sEM, $sSeq) = @_;

  return if($sEM eq "");

  $hSeq{$sEM} = $sSeq if(! exists $hSeq{$sEM});
  if(length($hSeq{$sEM}) < length($sSeq)){
    $hSeq{$sEM} = $sSeq;
  }
}


while(<DATA>){
  chomp;
  if(m/^[^>]/){
    $sSeq .= $_;
    next;
  }
  check_length($sEM, $sSeq);

  $sEM = (split)[1];
  $sSeq = "";
}

check_length($sEM, $sSeq);

foreach(sort keys %hSeq){
  print "> $_\n$hSeq{$_}\n";
}

__DATA__
>EM.1.1 EM.1 LK029911.1 +
CTGTCAATCCCGCACATTAAAGCATCTCTCTCCCCTTGCCTATTTTCTCGCCCCTTCCccatcctccttctctctcgctctctcctaGCATAGCTCCAAGCGCGAGGAACA
>EM.1.2 EM.1 LK029911.1 +
TCCTTTTAAGTACTGCAAACATACCTGGCGGCTTAAGCTTGCAGTATAATGTCAAGTGCTTCCCTACCACTTATTGCTTATAATTGTGATCACCCGTCAAATTGGTCGTTCTTGGAATATAGGCTCTTACTTTTAGAGCATGGTTATTTAAACAGGGGGACGAAAATCCCTCTTTGCTCAATGTAAGTCAGCTAGTTGTACTTACGTTTTGAACTCCACGTCCACACTGGAACAGCATTCGCTATGGACTGTGTCACACGACAAGCAGGTATGTTCATTT
>EM.1.3 EM.1 LK029911.1 +
CTGTCAATCCCGCACATTAAAGCATCTCTCTCCCCTTGCCTATTTTCTCGCCCCTTCCccatcctccttctctctcgctc

   

论坛徽章:
2
15-16赛季CBA联赛之山西
日期:2016-03-03 17:51:32CU十四周年纪念徽章
日期:2016-03-21 18:45:39
7 [报告]
发表于 2015-09-28 16:21 |只看该作者
回复 5# sunzhiguolu


    恩,试过了,是正确的,万分感谢,辛苦您了。我今天状态不对,没有认真学习的心思,老板今天又死揪着我不放,非常抱歉。

论坛徽章:
2
15-16赛季CBA联赛之山西
日期:2016-03-03 17:51:32CU十四周年纪念徽章
日期:2016-03-21 18:45:39
8 [报告]
发表于 2015-09-28 16:22 |只看该作者
回复 6# jason680


    非常不好意思,您指的问题我会一一改正,谢谢。

论坛徽章:
2
15-16赛季CBA联赛之山西
日期:2016-03-03 17:51:32CU十四周年纪念徽章
日期:2016-03-21 18:45:39
9 [报告]
发表于 2015-09-28 17:24 |只看该作者
回复 2# sunzhiguolu


    有一个小问题,就是最后的得到的每个序列的表头,后面都多了.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
10 [报告]
发表于 2015-09-28 17:32 |只看该作者
回复 9# 赛萌
再试下...

   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP