免费注册 查看新帖 |

ChinaUnix.net

  平台 论坛 博客 文库 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
最近访问板块 发新帖
查看: 3737 | 回复: 5

区间合并 [复制链接]

论坛徽章:
0
发表于 2018-05-08 21:53 |显示全部楼层
各位大侠晚上好!
向大家请教:一个文件中有两列,每一行是一个区域,顺序是从上向下递增
start          end
10467        10472
10469        10474
10482        10487
10487        10492
10491        10496
10495        10500
10523        10528
10540        10545
10561        10566
10569        10574
10575        10580

目的:当满足$end-$start(下一行)=1条件时,才合并该区域,如上述所示10492-10491=1,10496-10495=1;
得到最后结果应该是:10487   10500;
麻烦大家了!

论坛徽章:
0
发表于 2018-05-09 11:09 |显示全部楼层
# data input
my $line;
my (@start, @end);
my $i;

while ($line = <>) {
        chomp($line);
        my ($start, $end) = split(/\s+/, $line);
        print "$start\t\t$end\n";
        push @start, $start;
        push @end, $end;
}
print "\n\n";


# data merge
my (@first, @second);

if (@start) {
        push @first, $start[0];
        for ($i=0; $i<$#start; $i++) {
                if ($end[$i] - $start[$i + 1] != 1) {
                        push @second, $end[$i];
                        push @first, $start[$i + 1];
                }
        }
        push @second, $end[-1];
}

# show result
print "\n\n";
for ($i=0; $i<@first; $i++) {
        print "$first[$i]\t\t$second[$i]\n";
}

论坛徽章:
0
发表于 2018-05-10 10:19 |显示全部楼层
回复 2# flywithperl
多谢这位大侠,我也是你这种思路,写的比较坎坷,感谢帮忙!
想了下 另一种思路可以一次读两行进行判断!



论坛徽章:
0
发表于 2018-05-19 16:12 |显示全部楼层
逐行处理
  1. #!/usr/bin/env perl
  2. use strict;
  3. use warnings;
  4. use Data::Dumper;

  5. my @stack;
  6. while (<DATA>) {
  7.     my $rec = [split];
  8.     if (@stack) {
  9.         merge(\@stack, $rec);
  10.     } else {
  11.         push @stack, $rec;
  12.     }
  13. }

  14. print "@$_\n" for @stack;
  15. exit 0;

  16. sub merge {
  17.     my ($stack, $new) = @_;
  18.     my $last;
  19.     while (@$stack) {
  20.         $last = pop @$stack;
  21.         if ($last->[1] - $new->[0] == 1) {
  22.             $new = [ $last->[0], $new->[1] ];
  23.         } else {
  24.             push @$stack, $last;
  25.             last;
  26.         }
  27.     }
  28.     push @$stack, $new;
  29. }

  30. __DATA__
  31. 10467        10472
  32. 10469        10474
  33. 10482        10487
  34. 10487        10492
  35. 10491        10496
  36. 10495        10500
  37. 10523        10528
  38. 10540        10545
  39. 10561        10566
  40. 10569        10574
  41. 10575        10580
复制代码

论坛徽章:
0
发表于 2018-05-19 16:12 |显示全部楼层
逐行处理
  1. #!/usr/bin/env perl
  2. use strict;
  3. use warnings;
  4. use Data::Dumper;

  5. my @stack;
  6. while (<DATA>) {
  7.     my $rec = [split];
  8.     if (@stack) {
  9.         merge(\@stack, $rec);
  10.     } else {
  11.         push @stack, $rec;
  12.     }
  13. }

  14. print "@$_\n" for @stack;
  15. exit 0;

  16. sub merge {
  17.     my ($stack, $new) = @_;
  18.     my $last;
  19.     while (@$stack) {
  20.         $last = pop @$stack;
  21.         if ($last->[1] - $new->[0] == 1) {
  22.             $new = [ $last->[0], $new->[1] ];
  23.         } else {
  24.             push @$stack, $last;
  25.             last;
  26.         }
  27.     }
  28.     push @$stack, $new;
  29. }

  30. __DATA__
  31. 10467        10472
  32. 10469        10474
  33. 10482        10487
  34. 10487        10492
  35. 10491        10496
  36. 10495        10500
  37. 10523        10528
  38. 10540        10545
  39. 10561        10566
  40. 10569        10574
  41. 10575        10580
复制代码

论坛徽章:
11
子鼠
日期:2014-10-11 16:46:4815-16赛季CBA联赛之山东
日期:2017-11-10 14:32:142016科比退役纪念章
日期:2017-09-02 15:42:4715-16赛季CBA联赛之佛山
日期:2017-08-28 17:11:5515-16赛季CBA联赛之浙江
日期:2017-08-24 16:55:1715-16赛季CBA联赛之青岛
日期:2017-08-17 19:55:2415-16赛季CBA联赛之天津
日期:2017-06-29 10:34:4315-16赛季CBA联赛之四川
日期:2017-05-16 16:38:55黑曼巴
日期:2016-07-19 15:03:112015亚冠之萨济拖拉机
日期:2015-05-22 11:38:532016科比退役纪念章
日期:2018-03-16 10:24:05
发表于 2018-05-19 17:52 |显示全部楼层
本帖最后由 523066680 于 2018-05-19 17:55 编辑

如果数据量不大

  1. use File::Slurp;
  2. STDOUT->autoflush(1);

  3. my $data = read_file( "src.txt" );

  4. $data =~s/(\d+)\n(\d+)\s+/if ($1-$2 == 1) {print "Remove: $1 $2\n"; "";} else { ${&} }/eg;
  5. print $data;
复制代码

Remove: 10492 10491
Remove: 10496 10495
start          end
10467        10472
10469        10474
10482        10487
10487        10500
10523        10528
10540        10545
10561        10566
10569        10574
10575        10580

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

本版积分规则 发表回复

数据风云,十年变迁
DTCC 第十届中国数据库技术大会已启航!

2019年5月8日~5月10日,由IT168旗下ITPUB企业社区平台主办的第十届中国数据库技术大会(DTCC2019),将在北京隆重召开。大会将邀请百余位行业专家,就热点技术话题进行分享,是广大数据领域从业人士的又一次年度盛会和交流平台。与SACC2018类似,本届大会将采用“3+2”模式:3天传统技术演讲+2天深度主题培训。大会不仅提供超100场的主题演讲,还会提供连续2天的深度课程培训,深化数据领域的项目落地实践方案。
DTCC2019,一场值得期待的数据技术盛会,殷切地希望您报名参与!

活动入口>>
  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP