免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: 小猪Gina
打印 上一主题 下一主题

求助:perl hash中多元键和值的问题 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2012-12-10 11:05 |只看该作者
回复 9# kk861123
嗯,代码确实很简单,而且也比较好用。不过出了点小问题,比如文件:
a1           +               1           3
a1           +               6           8
a1           -               2           4
a1           -               5           6
a1           -               3           5
a1           -               7           8
a2           +               3           7
a2           -               1           5
a2           +               4           6
a2           -               7           9
a1           +               4           5
a1           +               2           5
期望结果:
a1 + 1 3 2 5 4 5 6 8
a1 - 2 4 3 5 5 6 7 8
a2 + 3 7 4 6
a2 - 1 5 7 9

您的运行结果:
a1        +        1        2        3        4        5        5        6        8
a1        -        2        3        4        5        5        6        7        8
a2        +        3        4        6        7
a2        -        1        5        7        9

另外还有个小问题,就如上面我们看到的结果中
a1 + 1 3 2 5 4 5 6 8
a1 - 2 4 3 5 5 6 7 8
a2 + 3 7 4 6
a2 - 1 5 7 9
它就是有重叠的部分,怎样将它们合并到一起,期望得到:
a1 + 1 5 6 8
a1 - 2 6 7 8
a2 + 3 7
a2 - 1 5 7 9

就像许多小线段,有重叠部分的就组合到一起,相当于数学中的求AUB吧。
谢谢您~


   

论坛徽章:
0
12 [报告]
发表于 2012-12-10 11:08 |只看该作者
本帖最后由 小猪Gina 于 2012-12-10 11:12 编辑


     额。。

论坛徽章:
0
13 [报告]
发表于 2012-12-10 11:11 |只看该作者
回复 10# mcshell
那个。。。您代码对我而言有点深奥,可以稍加注释么?麻烦您了。。谢谢~


   

论坛徽章:
0
14 [报告]
发表于 2012-12-10 11:17 |只看该作者
回复 10# mcshell
您的运行结果和九楼是一样的,没有得到期待结果。。。


   

论坛徽章:
3
CU十二周年纪念徽章
日期:2013-10-24 15:41:34子鼠
日期:2013-12-14 14:57:19射手座
日期:2014-04-25 21:23:23
15 [报告]
发表于 2012-12-10 11:30 |只看该作者
回复 14# 小猪Gina
那更简单一些。。。。
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use Data::Dumper;
  5. my %hash;
  6. my $title;
  7. while(<DATA>){
  8.     if(/(\w+\s+(?:\+|-))\s+(\d+\s+\d+)/){
  9.         push @{$hash{$1}},$2;
  10.     }else{
  11.         $title = $_;
  12.     }
  13. }
  14. map{print "$_\t";print join("\t",sort{$a cmp $b}@{$hash{$_}});print "\n"}sort keys %hash;

  15. __DATA__
  16. a1           +               1           3
  17. a1           +               6           8
  18. a1           -               2           4
  19. a1           -               5           6
  20. a1           -               3           5
  21. a1           -               7           8
  22. a2           +               3           7
  23. a2           -               1           5
  24. a2           +               4           6
  25. a2           -               7           9
  26. a1           +               4           5
  27. a1           +               2           5
复制代码

论坛徽章:
0
16 [报告]
发表于 2012-12-10 11:35 |只看该作者
回复 15# mcshell
厉害~
得出了
a1 + 1 3 2 5 4 5 6 8
a1 - 2 4 3 5 5 6 7 8
a2 + 3 7 4 6
a2 - 1 5 7 9
这个结果,那下一步怎么把它们连在一起呢?
您的代码我还在看,努力弄懂中~谢谢您了~

   

论坛徽章:
0
17 [报告]
发表于 2012-12-10 19:46 |只看该作者
my %hash=();
my @arrays = <IN>;
my @lie = sort {(split /\s+/,$a)[2] <=> (split /\s+/,$b)[2] }@arrays;

for (my $i=0;$i<=$#lie;$i++) {
        my @line=split(/\s+/,$lie[$i]);
        my($name,$direction,$start,$end)=("$line[0]","$line[1]","$line[2]","$line[3]");
        if (defined($hash{$name}{$direction})) {
                my @tmp=(@{$hash{$name}{$direction}},$start,$end);
                $hash{$name}{$direction}=\@tmp;
        }else{
                $hash{$name}{$direction}=[$start,$end];
        }   
}

foreach my $n (sort keys %hash) {
        foreach my $d (sort keys %{$hash{$n}} ) {
                for (my $j=0; $j<=$#{$hash{$n}{$d}}-2; $j=$j+2) {
                        if (${$hash{$n}{$d}}[$j+1]>=${$hash{$n}{$d}}[$j+2]) {
                                ${$hash{$n}{$d}}[$j+1]<=${$hash{$n}{$d}}[$j+3] ? (delete ${$hash{$n}{$d}}[$j+1] and delete ${$hash{$n}{$d}}[$j+2]) : (delete ${$hash{$n}{$d}}[$j+2] and delete ${$hash{$n}{$d}}[$j+3]);
                        }
                }
                print "$n $d @{$hash{$n}{$d}}\n";
        }
}
这个代码可以得到正确结果,可是有问题,就是运行到删掉的元素那个位置时会报错。。。。

论坛徽章:
0
18 [报告]
发表于 2012-12-11 15:53 |只看该作者
谢谢另一个大侠的帮助,已经解决了,代码如下:
my %hash=();
my @arrays = <IN>;
my @lie = sort {(split /\s+/,$a)[2] <=> (split /\s+/,$b)[2] }@arrays;

for (my $i=0;$i<=$#lie;$i++) {
        my @line=split(/\s+/,$lie[$i]);
        my($name,$direction,$start,$end)=("$line[0]","$line[1]","$line[2]","$line[3]";
        if (defined($hash{$name}{$direction})) {
                my @tmp=(@{$hash{$name}{$direction}},$start,$end);
                $hash{$name}{$direction}=\@tmp;
        }else{
                $hash{$name}{$direction}=[$start,$end];
        }   
}

foreach my $n (sort keys %hash) {
        foreach my $d (sort keys %{$hash{$n}} ) {
                for (my $j=$#{$hash{$n}{$d}}; $j>=3; $j=$j-2) {
                        if (${$hash{$n}{$d}}[$j-1]<=${$hash{$n}{$d}}[$j-2]) {
                                ${$hash{$n}{$d}}[$j]<=${$hash{$n}{$d}}[$j-2] ? (splice(@{$hash{$n}{$d}},$j,1) and splice(@{$hash{$n}{$d}},$j-1,1))splice(@{$hash{$n}{$d}},$j-1,1) and splice(@{$hash{$n}{$d}},$j-2,1));
                        }
                }
                print "$n $d @{$hash{$n}{$d}}\n";
        }
}
貌似太过臃肿,希望有大侠能帮我简化一下,感激~

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
19 [报告]
发表于 2012-12-12 00:41 |只看该作者
回复 16# 小猪Gina
  1. #!/user/bin/env perl
  2. use strict;
  3. my %hash;
  4. map{
  5.         my @data = split /\s+/,$_;
  6.         push @{$hash{join "\t",@data[0,1]}},[@data[2,3]]
  7. }<DATA>;

  8. foreach my $key (sort keys %hash){
  9.         my @output=();
  10.         map{
  11.                 my ($start,$end) = @{$_};
  12.                 @output = ($start,$end) if ! @output;
  13.                 $output[-1] < $start ? push(@output,($start,$end)) :
  14.                         $output[-1] < $end ? $output[-1] =  $end : "" ;
  15.                 $output[0] > $end ? splice(@output,0,0,($start,$end)) :       
  16.                         $output[0] > $start ? $output[0] = $start : "";
  17.         }sort{$a->[0] <=> $b->[0]}@{$hash{$key}};
  18.         print $key,"\t","@output";
  19.         print "\n";
  20. }
  21. __DATA__
  22. a1           +               1           3
  23. a1           +               6           8
  24. a1           -               2           4
  25. a1           -               5           6
  26. a1           -               3           5
  27. a1           -               7           8
  28. a2           +               3           7
  29. a2           -               1           5
  30. a2           +               4           6
  31. a2           -               7           9
  32. a1           +               4           5
  33. a1           +               2           5
复制代码
  1. a1 +    1 5 6 8
  2. a1 -    2 6 7 8
  3. a2 +    3 7
  4. a2 -    1 5 7 9
复制代码

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
20 [报告]
发表于 2012-12-12 08:48 |只看该作者
本帖最后由 rubyish 于 2012-12-12 04:50 编辑

简化一下:
  1. #!/usr/bin/perl -l
  2. my %h;
  3. /(\w+)\s+([+-])\s+(.*)/ and push @{$h{"$1 $2"}}, map [split],
  4.         $3 =~ /(\d+\s+\d+)/g while <DATA>;
  5. for my $k ( sort keys %h ) {
  6.     my ( @a, @t );
  7.     @t && $t[1] >= $_->[0]
  8.       ? do { $t[1] = $t[1] > $_->[1] ? $t[1] : $_->[1] }
  9.       : do { push @a, [@t]; @t = @$_ }
  10.       for sort { $a->[0] <=> $b->[0] } @{$h{$k}};
  11.     print join ' ', $k, map @$_, @a, [@t];
  12. }
  13. __DATA__
  14. a1           +               1           3
  15. a1           +               6           8
  16. a1           -               2           4
  17. a1           -               5           6
  18. a1           -               3           5
  19. a1           -               7           8
  20. a2           +               3           7
  21. a2           -               1           5
  22. a2           +               4           6
  23. a2           -               7           9
  24. a1           +               4           5
  25. a1           +               2           5
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP