Chinaunix
标题:
求助,这代码如何写?
[打印本页]
作者:
yumiao5642
时间:
2012-12-21 16:53
标题:
求助,这代码如何写?
本帖最后由 yumiao5642 于 2012-12-21 16:56 编辑
现有一数百行的数据,内容类似如下(全部为大于1,小于100的数值)
每行9个数,需要其中任意4个相加,取值并减去上一行中第3个到第9个中任意数值,如结果为31的倍数则计为匹配(结果为0也算匹配,如果一个公式在一行中匹配了多个数值则只记为一次)
比如第三行49+84+82+22=247, 减去第二行中的30和92都为31的倍数,但只记匹配成功一次.
目的是统计每个公式的匹配次数,最终列出前五名和后五名的计算公式和匹配次数.
有感兴趣请帮帮忙,如果表达的不清楚可以随时问,谢谢了
30 12 38 40 34 30 47 25 83
30 12 24 8 30 49 26 9 92
30 12 49 26 27 84 24 82 22
30 12 47 22 25 5 8 43 37
30 12 49 8 85 35 88 82 87
30 12 5 86 48 46 82 87 85
30 12 25 44 4 82 42 88 8
30 12 27 80 84 49 39 28 25
30 12 39 34 9 48 33 7 48
30 12 82 33 34 20 3 48 43
30 12 88 30 48 45 86 34 47
30 12 6 20 27 82 86 38 7
30 12 45 84 20 38 46 28 47
30 12 29 42 46 28 27 22 49
30 12 80 34 3 88 29 87 85
30 12 20 47 80 88 84 34 48
30 12 88 84 2 39 25 8 38
30 12 36 24 44 86 35 23 8
30 12 36 80 24 83 20 29 84
30 12 44 36 27 48 85 32 47
30 12 26 38 35 20 3 32 82
30 12 38 3 7 32 80 35 30
30 12 33 48 88 46 9 43 2
30 12 38 5 82 37 45 34 80
30 12 27 3 44 40 2 49 38
30 12 39 23 7 28 80 29 8
30 12 30 8 37 48 38 38 5
30 12 27 87 24 4 8 43 48
30 12 49 37 5 88 86 28 24
30 12 43 38 26 39 49 37 2
30 12 8 38 35 23 2 46 5
30 12 28 29 43 47 9 34 32
30 12 40 36 38 3 25 32 38
30 12 3 42 28 25 84 27 34
30 12 20 28 22 36 48 5 8
30 12 5 8 88 2 43 6 25
30 12 88 37 3 2 9 23 38
30 12 22 33 8 8 28 3 5
30 12 83 6 42 40 37 3 29
30 12 39 33 47 42 22 4 84
30 12 35 3 48 38 5 88 32
30 12 24 43 28 47 38 7 5
30 12 84 22 83 80 47 82 28
30 12 20 28 22 36 48 5 9
30 12 5 9 99 2 43 6 25
30 12 98 37 3 2 9 23 39
30 12 22 33 9 8 28 3 5
30 12 93 6 42 40 37 3 29
30 12 39 33 47 42 22 4 94
30 12 35 3 49 38 5 98 32
30 12 24 43 29 47 39 7 5
30 12 94 22 93 90 47 92 29
作者:
rubyish
时间:
2012-12-21 22:06
不清楚计算公式:
#!/usr/bin/perl
use 5.016;
my @t = ( split /\s+/, <DATA> )[ 2 .. 8 ];
my %p;
while (<DATA>) {
my @a = split;
my $g = '{' . join( '|,', @a ) . '|}';
my $q;
for my $i ( glob $g x 4 ) {
my @b = split /\|/, $i;
my $s;
next unless keys %{ { map { $_, 1 } @b } } == 4;
$s += $_ for @b;
for my $t (@t) {
say "l-$.\t@b\t$t\tok" and $q++ if ( $s - $t ) % 31 == 0;
last if $q;
}
last if $q;
}
@t = @a[ 2 .. 8 ];
}
__DATA__
30 12 38 40 34 30 47 25 83
30 12 24 8 30 49 26 9 92
30 12 49 26 27 84 24 82 22
30 12 47 22 25 5 8 43 37
30 12 49 8 85 35 88 82 87
30 12 5 86 48 46 82 87 85
30 12 25 44 4 82 42 88 8
复制代码
l-2 30 12 24 26 30 ok
l-3 30 12 49 26 24 ok
l-4 30 12 47 22 49 ok
l-5 30 12 49 8 37 ok
l-6 30 12 5 85 8 ok
l-7 30 12 25 82 87 ok
l-8 30 12 27 80 25 ok
l-9 30 12 39 34 84 ok
l-10 30 12 82 33 33 ok
l-11 30 12 88 45 82 ok
l-12 30 12 6 38 86 ok
l-13 30 12 20 38 38 ok
复制代码
作者:
rubyish
时间:
2012-12-22 12:03
speed up yi xia:
#!/usr/bin/perl
use 5.016;
my @t = ( split /\s+/, <DATA> )[ 2 .. 8 ];
my %p;
while (<DATA>) {
my @a = split;
my $g = join '', map { '{' . join( '|,', @a[ $_ .. @a + $_ - 4 ] ) . '|}' } 0 .. 3;
my $q;
for my $i ( glob $g ) {
my @b = split /\|/, $i;
my $s;
next unless keys %{ { map { $_, 1 } @b } } == 4;
$s += $_ for @b;
for my $t (@t) {
say "l-$.\t@b\t$t\tok" and $q++ if ( $s - $t ) % 31 == 0;
last if $q;
}
last if $q;
}
@t = @a[ 2 .. 8 ];
}
__DATA__
30 12 38 40 34 30 47 25 83
30 12 24 8 30 49 26 9 92
30 12 49 26 27 84 24 82 22
30 12 47 22 25 5 8 43 37
30 12 49 8 85 35 88 82 87
30 12 5 86 48 46 82 87 85
30 12 25 44 4 82 42 88 8
30 12 27 80 84 49 39 28 25
30 12 39 34 9 48 33 7 48
复制代码
作者:
yumiao5642
时间:
2012-12-22 22:12
回复
3#
rubyish
谢谢,,我只看过两遍perl入门的基础书,但代码勉强看懂了.
你给的代码找出了每行哪四个数字可以组合匹配上一行,,但我需要的是哪个固定位置的四个数组合可以匹配次数最多....
比如第1位+第3位+第5位+第7位. 全部计算完以后总共匹配了100次.
而第2位+第4位+第6位+第8位. 全部计算完以后总共匹配80次.
...
...
最终找出匹配次数最多的计算方式....应该有办法吧?我写不出来,,,请再帮帮忙,谢谢,费心了!!
作者:
rubyish
时间:
2012-12-23 10:14
本帖最后由 rubyish 于 2012-12-23 06:32 编辑
是否:
#!/usr/bin/perl
use 5.016;
use Math::Combinatorics;
my %r;
my @n = reverse 0 .. 8;
my @test = combine( 4, @n );
my @data = map { [split] } <DATA>;
my @first = @{ $data[0] }[ 2 .. 8 ];
for (@test) {
my @index = @$_;
my @last = @first;
for my $d ( @data[ 1 .. $#data ] ) {
my @d = @$d;
my $s;
$s += $_ for @d[@index];
for my $l (@last) {
next unless ( $s - $l ) % 31 == 0;
$r{"@index"}++ and last;
}
@last = @d[ 2 .. 8 ];
}
}
say "$_ = $r{$_}" for ( sort { $r{$b} <=> $r{$a} } keys %r )[ 0 .. 4, -5 .. -1];
__DATA__
30 12 38 40 34 30 47 25 83
30 12 24 8 30 49 26 9 92
30 12 49 26 27 84 24 82 22
30 12 47 22 25 5 8 43 37
30 12 49 8 85 35 88 82 87
30 12 5 86 48 46 82 87 85
复制代码
0 1 2 3 = 19
1 2 4 7 = 17
1 4 5 6 = 16
0 1 5 7 = 16
1 2 6 7 = 16
1 4 7 8 = 4
2 4 5 8 = 4
0 3 4 8 = 4
0 1 3 5 = 4
0 1 3 8 = 3
复制代码
0 1 2 3 第1位 + 第2位 + 第3位 + 第4位
作者:
yumiao5642
时间:
2012-12-23 23:07
回复
5#
rubyish
就是这个,,太感谢了,太强大了...
希望有一天我也能达到这个层次......学习,,,努力中.再次感谢!
作者:
rubyish
时间:
2012-12-24 09:19
本帖最后由 rubyish 于 2012-12-24 05:19 编辑
fix version:
#!/usr/bin/perl
use 5.016;
use Math::Combinatorics;
my @n = reverse 0 .. 8;
my @test = combine( 4, @n );
my @last = ( map { split } scalar <DATA> )[ 2 .. 8 ];
my %r = map { join( ' ', @$_ ), 0 } @test;
while (<DATA>) {
my @d = split;
for my $t (@test) {
my @index = @$t;
my $s = eval join '+', @d[@index];
( $s - $_ ) % 31 == 0 and $r{"@index"}++ and last for @last;
}
@last = @d[ 2 .. 8 ];
}
say "$_ = $r{$_}" for ( sort { $r{$b} <=> $r{$a} } keys %r )[ 0 .. 4, -5 .. -1 ];
_DATA__
30 12 38 40 34 30 47 25 83
30 12 24 8 30 49 26 9 92
30 12 49 26 27 84 24 82 22
复制代码
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2