具体来说,通过perl中的文件进行迭代

时间:2015-09-16 23:10:56

标签: perl

所以,我有这个脚本:

python/pid_number

哪个在测试文件上运行如下:

#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use Math::Vector::Real;
use constant DEG_PER_RAD => 45 / atan2(1, 1);

my ( $source, $out ) = qw/ OUT4 OUTABA12 /;

open my $in_fh,  '<', $source or die qq{Unable to open "$source" for input: $!\n};
open my $out_fh, '>', $out    or die qq{Unable to open "$out" for output: $!\n};


my @data;
push @data, V(split) while <$in_fh>;
my @aoa;

for my $i ( 0 .. $#data ) {
    for my $j ( 0 .. $#data ) {
        my $val1 = $data[$i];
        my $val2 = $data[$j];

        if ($val1 != $val2) {

            my $math = sqrt(($val1->[0] - $val2->[0])**2 +
                ($val1->[1] - $val2->[1])**2 +
                ($val1->[2] - $val2->[2])**2);

                if ($math < 2.2) {
                print "@$val1 @$val2 $math\n";
                    push @aoa, [@$val1, @$val2, $math];
                    }
        }
    }
}

for my $k ( 0 .. $#aoa-1 ) {

        my $aoadata1 = $aoa[$k];
        my $aoadata2 = $aoa[$k+1];

        my $vect1 = [ @{ $aoa[$k] }[0..2] ];
        my $vect2 = [ @{ $aoa[$k+1] }[0..2] ];
        my $vect3 = [ @{ $aoa[$k] }[3..5] ];
        my $vect4 = [ @{ $aoa[$k+1] }[3..5] ];
        my $math1 = [ @{ $aoa[$k] }[6] ];
        my $math2 = [ @{ $aoa[$k+1] }[6] ];

        my @matha = @$math1;
        my @mathb = @$math2;
        my @vecta = @$vect1;
        my @vectb = @$vect2;
        my @vectc = @$vect3;
        my @vectd = @$vect4;

            if ( @vecta != @vectb ) {

                print "1\n";

                }
}

并计算每个点与其他每个点之间的距离,如果它低于阈值,则将其推送到数组以供日后使用。 (出于测试目的,我也打印它。)

我一直坚持的是下半部分 - 我试图最终达到脚本脚本的下半部分在行之间迭代的程度:

如果第1行的第一组三组值与第二行的第一组三元组值不同,则打印180,但前提是这是此行的唯一实例。如果行第一行的值等于第二行,则不要打印180。

对于我的生活,我不能让它发挥作用。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

我认为这是正确的

我使用了Math::Vector::Real模块的功能,如我在评论中所述

  • 我将矢量作为对象,并避免直接访问其内容

  • 我将$vec1$vec2之间的距离计算为abs($vec1 - $vec2

  • 我使用该课程的 stringify 功能来显示它,而不是在我的代码中提取单个值

我也改变了中间数据格式。距离不再保留,因为它不是必需的,并且数组@groups现在包含具有共同第一向量的每组向量对的数组。每个组的格式为

[ $vec1, $vec2, $vec2, $vec2, ... ]

我使用List::Util中的first函数来查找每个新向量对所属的组。如果找到一个匹配的第一个值的现有组,那么第二个向量就被推到小组结束;否则会创建一个看起来像[ $vec1, $vec2 ]

的新组

构建@groups数组后,将再次处理它以生成输出

  • 如果组中只有两个值,则它们是唯一点的$vec1$vec2$vec1打印有180

  • 如果有两个以上的元素,则为每对$vec2值生成一行输出,每个值包含值$vec1以及两个{{1}之间的角度对中的向量


$vec2

输出

use strict;
use warnings;

use Math::Vector::Real qw/ V /;
use List::Util qw / first /;

use constant DEG_PER_RAD => 45 / atan2(1, 1);

my ( $source, $out ) = qw/ OUT4 OUTABA12 /;

open my $in_fh,  '<', $source or die qq{Unable to open "$source" for input: $!\n};

my @data = map V(split), <$in_fh>;

my @groups;

for my $vec1 ( @data ) {

    for my $vec2 ( @data ) {

        next if abs($vec1 - $vec2) > 2.2 or $vec1 == $vec2;

        my $group = first { $_->[0] == $vec1 } @groups;

        if ( $group ) {
            push @$group, $vec2;
        }
        else {
            push @groups, [ $vec1, $vec2 ];
        }
    }
}

open my $out_fh, '>', $out or die qq{Unable to open "$out" for output: $!\n};
select $out_fh;

for my $group ( @groups ) {

    my ($vec1, @vec2) = @$group;

    if ( @vec2 == 1 ) {
        print "$vec1 180\n";
        next;
    }

    for my $i ( 0 .. $#vec2-1 ) {
        for my $j ( $i+1 .. $#vec2 ) {
            my ($vec2a, $vec2b) = @vec2[$i, $j];
            my $angle = atan2( $vec2a, $vec2b ) * DEG_PER_RAD;
            print "$vec1 $angle\n";
        }
    }

}