Chinaunix

标题: 求教各位大大们,这个问题用perl怎么处理 [打印本页]

作者: mingoing    时间: 2014-02-27 09:37
标题: 求教各位大大们,这个问题用perl怎么处理
本帖最后由 mingoing 于 2014-02-27 11:31 编辑


7400000 8200000  -747.871582
8200000 8500000  -311.464386
8500000 9100000  -552.063538
9100000 9800000  -691.326904
9800000 10700000  -860.887024
10700000 11500000  -775.908630
11500000 12300000  -748.672424
12300000 13200000  -868.078918
13200000 14100000  -844.211609
14100000 14600000  -531.665039
14600000 15500000  -934.396790
15500000 16300000  -808.178162
16300000 17500000  -1163.265747
17500000 17900000  -425.282043
17900000 18900000  -937.942383
18900000 19600000  -743.132019
19600000 20800000  -1200.120850
20800000 21100000  -285.289520
先上图,图中每一行前两个数字相当于左端点右端点,拿第一行来说,相当于在[7400000, 8200000]范围内取值-747.871582。我想得到[8650000,9750000] ,[13250000,13950000],[17650000,18850000]这几个范围内的值。PS:跨范围的取加权平均。{:2_172:}   
作者: q1208c    时间: 2014-02-27 09:39
表示没看懂.

在两个整数区间里, 你想取个 负数 ... ...
作者: mingoing    时间: 2014-02-27 09:42
相当于分段函数吧,前两个数是分段函数的小段定义域回复 2# q1208c


   
作者: xiumu2280    时间: 2014-02-27 10:16
本帖最后由 xiumu2280 于 2014-02-27 10:16 编辑

楼主的意思是不是  每一行取个平均值。
然后按照这个平均值,来算[8650000,9750000] ,[13250000,13950000],[17650000,18850000]这几个区域分别的和?

还有不要用图片给原始数据···怎么测试···
作者: mingoing    时间: 2014-02-27 10:21
本帖最后由 mingoing 于 2014-02-27 10:22 编辑

这种理解也对{:3_189:} ,数据:
7400000 8200000  -747.871582
8200000 8500000  -311.464386
8500000 9100000  -552.063538
9100000 9800000  -691.326904
9800000 10700000  -860.887024
10700000 11500000  -775.908630
11500000 12300000  -748.672424
12300000 13200000  -868.078918
13200000 14100000  -844.211609
14100000 14600000  -531.665039
14600000 15500000  -934.396790
15500000 16300000  -808.178162
16300000 17500000  -1163.265747
17500000 17900000  -425.282043
17900000 18900000  -937.942383
18900000 19600000  -743.132019
19600000 20800000  -1200.120850
20800000 21100000  -285.289520
回复 4# xiumu2280


   
作者: mingoing    时间: 2014-02-27 10:32
比如计算[17650000,18850000]范围内的值:
(17900000-17650000)/(18850000-17650000)*(-425.282043)+(18850000-1790000)/(18850000-17650000)*(-937.942383)
作者: mingoing    时间: 2014-02-27 10:32
本帖最后由 mingoing 于 2014-02-27 10:46 编辑

比如计算[17650000,18850000]范围内的值:设L=(18850000-17650000),L1=(17900000-17650000),L2=(18850000-1790000),那么最终得到:L1/L*(-425.282043)+L2/L*(-937.942383)
作者: mingoing    时间: 2014-02-27 17:11
我把程序搞成这样了
  1. open A,"mono_align1\.mlf";
  2. open L,"recout_mon16_phone1\.mlf";
  3. open OUT,">","out.txt";
  4. while (<A>){
  5.         chomp;
  6.         next if /MLF|lab/;
  7.         my ($data1,$data2,$phone1,$score1)=split/\s+/,$_;
  8.         print OUT "$_ ";
  9.         while (<L>){
  10.                 chomp;
  11.                 next if /MLF|rec/;
  12.                 my ($data3,$data4,$phone2,$score2)=split/\s+/,$_;
  13.                 if ($data1>$data3&$data2<$data4){
  14.                         print OUT "$score2\n";
  15.                         last;
  16.                 }
  17.                 if ($data1>$data3&$data2>$data4){
  18.                         my $nnn=($data4-$data1)/($data2-$data1)*$score2;
  19.                         print OUT "\"$_\"\n";
  20.                         &handle($nnn, $data2, $_);
  21. #                        my ($data4,$data5,$phone3,$score3)=split/\s+/,$_;
  22. #                        if ($data2<$data5){
  23. #                                $nnn=$nnn+($data2-$data4)/($data2-$data1)*$score3;
  24. #                                print OUT "$nnn\n";
  25.                                 last;
  26. #                        }
  27.                 }
  28.     print OUT "\n";
  29.         }
  30.        
  31. }

  32. sub handle
  33. {
  34.         my $nnn = shift;
  35.         my $data2 = shift;
  36.         my $yyy = shift;
  37.         open OOO, ">","22.txt";
  38.         my $line = <L>;
  39.         chomp($line);
  40.         print OOO "$line";
  41.         my ($data4,$data5,$phone3,$score3)=split/\s+/,$yyy;
  42.         if ($data2<$data5){
  43.                 $nnn=$nnn+($data2-$data4)/($data2-$data1)*$score3;
  44.                 return;
  45.         }
  46.         return;
  47. }
复制代码

作者: xiumu2280    时间: 2014-02-27 19:52
本帖最后由 xiumu2280 于 2014-02-27 20:05 编辑
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use Data::Dumper;
  5. use File::Basename;


  6. my %hash;
  7. while (<DATA>) {
  8.         chomp;
  9.         my @data = split;
  10.         my $aver = $data[2]/($data[1]-$data[0]);
  11.         my @da = $data[0]..$data[1];
  12.         @hash{@da}= ($aver) x scalar (@da);
  13. }

  14. my @data = ([8650000,9750000],[13250000,13950000],[17650000,18850000]);
  15. foreach my $uniq (@data) {
  16.         my $n = 0;
  17.         foreach my $cell ($uniq->[0]..$uniq->[1]) {
  18.                 $n += $hash{$cell};
  19.         }
  20.         print "$n\n";
  21. }



  22. __DATA__
  23. 7400000 8200000  -747.871582
  24. 8200000 8500000  -311.464386
  25. 8500000 9100000  -552.063538
  26. 9100000 9800000  -691.326904
  27. 9800000 10700000  -860.887024
  28. 10700000 11500000  -775.908630
  29. 11500000 12300000  -748.672424
  30. 12300000 13200000  -868.078918
  31. 13200000 14100000  -844.211609
  32. 14100000 14600000  -531.665039
  33. 14600000 15500000  -934.396790
  34. 15500000 16300000  -808.178162
  35. 16300000 17500000  -1163.265747
  36. 17500000 17900000  -425.282043
  37. 17900000 18900000  -937.942383
  38. 18900000 19600000  -743.132019
  39. 19600000 20800000  -1200.120850
  40. 20800000 21100000  -285.289520
复制代码
这个非常耗内存。运行这点要2G内存··· 如果你都是后面5个0没用的话可以舍去··· 会节省很多内存
  1. -1055.99505195218
  2. -656.60996723752
  3. -1156.84747864572
复制代码

作者: pitonas    时间: 2014-02-27 20:57
{:2_172:}是不是
  1. [8650000, 9750000]      = -634.355527
  2. [13250000, 13950000]    = -911.185874
  3. [17650000, 18850000]    = -831.1381455
复制代码
  1. #!/usr/bin/perl

  2. my @range = (
  3.           [ 8650000, 9750000 ],
  4.           [ 13250000, 13950000 ],
  5.           [ 17650000, 18850000 ],
  6. );
  7.          
  8. @range = sort { $a->[0] <=> $b->[0] } @range;
  9. my $index = 0;
  10. my @data  = map { [split] } <DATA>;

  11. loop: for my $R (@range) {
  12.     my $L = $R->[1] - $R->[0];
  13.     my $ave;
  14.     for my $i ( $index .. $#data ) {
  15.         next if $R->[0] > $data[$i][1];
  16.         $index = $i;
  17.         my ( $r1, $r2, $v ) = @{ $data[$i] };
  18.         $ave += ( $r2 - $R->[0] ) / $L * $v;

  19.         for my $j ( $index + 1 .. $#data ) {
  20.             my ( $r1, $r2, $v ) = @{ $data[$j] };
  21.             $ave += ( $r2 - $r1 ) / $L * $v and next if $R->[1] > $r2;
  22.             $ave += ( $R->[1] - $r1 ) / $L * $v;
  23.             print "[$R->[0], $R->[1]]\t= $ave\n";
  24.             next loop;
  25.         }
  26.     }
  27. }

  28. __DATA__
  29. 7400000 8200000  -747.871582
  30. 8200000 8500000  -311.464386
  31. 8500000 9100000  -552.063538
  32. 9100000 9800000  -691.326904
  33. 9800000 10700000  -860.887024
  34. 10700000 11500000  -775.908630
  35. 11500000 12300000  -748.672424
  36. 12300000 13200000  -868.078918
  37. 13200000 14100000  -844.211609
  38. 14100000 14600000  -531.665039
  39. 14600000 15500000  -934.396790
  40. 15500000 16300000  -808.178162
  41. 16300000 17500000  -1163.265747
  42. 17500000 17900000  -425.282043
  43. 17900000 18900000  -937.942383
  44. 18900000 19600000  -743.132019
  45. 19600000 20800000  -1200.120850
  46. 20800000 21100000  -285.289520
复制代码

作者: mingoing    时间: 2014-02-28 09:11
快了,貌似[13250000, 13950000]    = -911.185874还有点问题,因为[13250000, 13950000] 是在区间[13200000 14100000]内的,所以直接可以确定为-844.211609。{:2_172:} 回复 10# pitonas


   
作者: mingoing    时间: 2014-02-28 09:16
我研究一下 回复 9# xiumu2280


   
作者: pitonas    时间: 2014-02-28 10:05
{:2_172:} 多谢提醒
  1. [8650000, 9750000]      = -634.355527
  2. [13250000, 13950000]    = -844.211609
  3. [17650000, 18850000]    = -831.1381455
复制代码
  1. #!/usr/bin/perl

  2. my @range = (
  3.           [ 8650000, 9750000 ],
  4.           [ 13250000, 13950000 ],
  5.           [ 17650000, 18850000 ],
  6. );
  7.          
  8. @range = sort { $a->[0] <=> $b->[0] } @range;
  9. my $index = 0;
  10. my @data  = map { [split] } <DATA>;

  11. range: for my $R (@range) {
  12.     my $L = $R->[1] - $R->[0];
  13.     my $ave;
  14.     for my $i ( $index .. $#data ) {
  15.         next if $R->[0] > $data[$i][1];
  16.         $index = $i;
  17.         my ( $r1, $r2, $v ) = @{ $data[$i] };
  18.         if ( $R->[1] <= $r2 ) {
  19.             print "[$R->[0], $R->[1]]\t= $v\n";
  20.             next range;
  21.         }
  22.         $ave += ( $r2 - $R->[0] ) / $L * $v;

  23.         for my $j ( $index + 1 .. $#data ) {
  24.             my ( $r1, $r2, $v ) = @{ $data[$j] };
  25.             $ave += ( $r2 - $r1 ) / $L * $v and next if $R->[1] > $r2;
  26.             $ave += ( $R->[1] - $r1 ) / $L * $v;
  27.             print "[$R->[0], $R->[1]]\t= $ave\n";
  28.             next range;
  29.         }
  30.     }
  31. }

  32. __DATA__
  33. 7400000 8200000  -747.871582
  34. 8200000 8500000  -311.464386
  35. 8500000 9100000  -552.063538
  36. 9100000 9800000  -691.326904
  37. 9800000 10700000  -860.887024
  38. 10700000 11500000  -775.908630
  39. 11500000 12300000  -748.672424
  40. 12300000 13200000  -868.078918
  41. 13200000 14100000  -844.211609
  42. 14100000 14600000  -531.665039
  43. 14600000 15500000  -934.396790
  44. 15500000 16300000  -808.178162
  45. 16300000 17500000  -1163.265747
  46. 17500000 17900000  -425.282043
  47. 17900000 18900000  -937.942383
  48. 18900000 19600000  -743.132019
  49. 19600000 20800000  -1200.120850
  50. 20800000 21100000  -285.289520
复制代码
回复 11# mingoing


   
作者: mingoing    时间: 2014-02-28 11:05
哥们太赞了,学习了{:2_172:} 回复 13# pitonas


   
作者: kernel69    时间: 2014-02-28 20:29
来个想要求出结果的栗子
回复 1# mingoing


   




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2