免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3475 | 回复: 10

perl:从两组数据找出满足一定条件的结果 [复制链接]

论坛徽章:
0
发表于 2014-08-20 16:57 |显示全部楼层
本帖最后由 pony2001mx 于 2014-08-20 20:36 编辑

大家好:
下面是一个困扰我的问题。举个例子,我有两组数据data1和data2,如下所示。
data1(班级--姓名--分数)
class1 wang 60
class1 liu 60
class1 ma 60
class2 niu 60
class2 bai 63

data2(姓名--组)
wang group1
liu group1
ma group2
niu group3
bai group3

我需要输出data1中满足以下条件的数据行:属于同一个class属于同一个group有相同的分数。例如上面的数据应输出的行是前两行。

我试图把data1变成成hash的hash的hash,data2变成hash的hash,但之后怎么也想不出如何输出结果,希望指点迷津!谢谢!!

论坛徽章:
0
发表于 2014-08-20 20:36 |显示全部楼层
请教高手!!

论坛徽章:
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
发表于 2014-08-20 20:47 |显示全部楼层
本帖最后由 stanley_tam 于 2014-08-20 20:50 编辑

哈希不行就换数组把{:3_193:}
  1. #!perl
  2. use strict;
  3. use FileHandle;

  4. my $file1 = 'data1.txt';
  5. my $file2 = 'data2.txt';

  6. # load group data
  7. my @lines = FileHandle->new($file2, 'r')->getlines;
  8. chomp @lines;
  9. my %group_of = map {split /\s+/, $_, 2} @lines;

  10. # go through data1.txt
  11. my $data = +{};
  12. my $fh1 = FileHandle->new($file1, 'r');

  13. while (my $line = $fh1->getline) {
  14.     chomp $line;
  15.     my ($class, $name, $score) = split /\s+/, $line, 3;

  16.     my $group = $group_of{$name};

  17.     # index is score
  18.     push @{ $data->{"$class-$group"}->[$score] }, $line;
  19. }
  20. $fh1->close;

  21. for my $key (keys %{$data}){
  22.     my $aref = $data->{$key};

  23.     my $last_score = undef;
  24.     my %valid_index = ();
  25.     for my $score (0 .. $#{$aref}){
  26.         next if not $aref->[$score];

  27.         if (defined $last_score and abs($score - $last_score) < 5) {
  28.             ++$valid_index{$last_score};
  29.             ++$valid_index{$score};
  30.         }

  31.         $last_score = $score;
  32.     }

  33.     for my $i (keys %valid_index){
  34.         print "$_\n" for @{ $aref->[$i] };
  35.     }

  36. }


  37. __END__
复制代码

论坛徽章:
0
发表于 2014-08-20 21:02 |显示全部楼层
非常感谢stanley_tam的perl代码。我真的需要仔细研读。谢谢!!

论坛徽章:
8
技术图书徽章
日期:2013-08-22 11:21:28未羊
日期:2015-01-19 22:22:25巳蛇
日期:2014-08-11 16:53:08子鼠
日期:2014-05-29 09:04:44摩羯座
日期:2014-04-11 14:15:07丑牛
日期:2014-01-24 12:41:28金牛座
日期:2013-11-21 17:38:28射手座
日期:2015-01-21 08:50:32
发表于 2014-08-20 21:05 |显示全部楼层
  1. #!/usr/bin/perl -w
  2. my %h;
  3. open GR,"< group.txt" || die "$!";
  4. my %f = map{ split }<GR>;
  5. close GR;

  6. open CL,"< class.txt"|| die "$!";
  7. while(<CL>){
  8.         my($class, $name, $point) = (split);
  9.         next unless exists $f{$name};
  10.         my $key = $class.$f{$name}.$point;
  11.         push @{$h{$key}},$_;
  12. }
  13. close CL;

  14. foreach my $key (keys %h){
  15.                         print "@{$h{$key}}" if $#{$h{$key}} >0;
  16. }
复制代码
乱写的,您随便参考参考

论坛徽章:
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
发表于 2014-08-20 21:19 |显示全部楼层
本帖最后由 stanley_tam 于 2014-08-20 21:20 编辑

不是分数相差5分内的吗,呵呵{:3_182:}

论坛徽章:
0
发表于 2014-08-20 21:22 |显示全部楼层
谢谢huang6894的慷慨!
注:我最早的帖子是分数相差小于5,所以stanley_tam的perl code里写了abs($score - $last_score) < 5)的语句;但我后来为了简化起见,要求分数相同,这就是huang给我的答案。谢谢!

论坛徽章:
0
发表于 2014-08-20 21:24 |显示全部楼层
stanley_tam,我看没人回我的帖子,所以简化了条件,谢谢你的帮助!!

论坛徽章:
8
技术图书徽章
日期:2013-08-22 11:21:28未羊
日期:2015-01-19 22:22:25巳蛇
日期:2014-08-11 16:53:08子鼠
日期:2014-05-29 09:04:44摩羯座
日期:2014-04-11 14:15:07丑牛
日期:2014-01-24 12:41:28金牛座
日期:2013-11-21 17:38:28射手座
日期:2015-01-21 08:50:32
发表于 2014-08-21 08:51 |显示全部楼层
回复 7# pony2001mx


    那就改改吧~
  1. #!/usr/bin/perl -w
  2. my %h;
  3. open GR,"< group.txt" || die "$!";
  4. my %f = map{ split }<GR>;
  5. close GR;

  6. open CL,"< class.txt"|| die "$!";
  7. while(my $line = <CL>){
  8.         chomp($line);
  9.         my($class, $name, $point) = (split /\s+/,$line);
  10.         next unless exists $f{$name};
  11.         my $key = $class.$f{$name}.$point;
  12.         foreach my $i ($point-5..$point+5){
  13.                 my $key2 = $class.$f{$name}.$i;
  14.                 if ($#{$h{$key2}}>=0){
  15.                         push @{$h{$key2}},$line;
  16.                         }
  17.                 }
  18.         push @{$h{$key}},$line if $#{$h{$key}} <0;
  19. }
  20. close CL;

  21. foreach my $key (keys %h){
  22.                         print join("\n",@{$h{$key}}).$/.$/ if $#{$h{$key}} >0;
  23. }
复制代码
求大神莫拍~~~~~~~~~~

论坛徽章:
33
荣誉会员
日期:2011-11-23 16:44:17天秤座
日期:2014-08-26 16:18:20天秤座
日期:2014-08-29 10:12:18丑牛
日期:2014-08-29 16:06:45丑牛
日期:2014-09-03 10:28:58射手座
日期:2014-09-03 16:01:17寅虎
日期:2014-09-11 14:24:21天蝎座
日期:2014-09-17 08:33:55IT运维版块每日发帖之星
日期:2016-04-17 06:23:27操作系统版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-24 06:20:0015-16赛季CBA联赛之天津
日期:2016-05-06 12:46:59
发表于 2014-08-21 09:33 |显示全部楼层
典型的数据库 select 操作.

把这两个文件放进数据库的两张表, 再按条件 select 出来就行了.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP