文件行对抗 [英] File row confrontation

查看:68
本文介绍了文件行对抗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下问题:来自具有以下格式数据的文件 (file.dat)

I have the following problem: from a file (file.dat) with the following formatted datas

1 2 3 4
2 1 3 4 5
3 1 2
4 1 2
5 2 6 7
6 5 8
7 5 8
8 6 7 9
9 8

我想找:

  1. 如果一行的第一个元素出现在其他行中,并且后续行的第一个元素出现在考试的行中;
  2. 如果它存在,那么我想打印I have found the link x y";
  3. 如果link"存在,那么我想计算在考试中采取的行中的其他元素出现在存在链接的行中的次数并打印I找到了 z 个三角形".
  1. if the first element of a row appears in the other rows and if the first element of the subsequent rows appear in the row taken in exam;
  2. if it exists then I want to print "I have found the link x y";
  3. if the "link" exists, then I want to count how many times the other elements in the row taken in exam appear in the row where the link is present and print "I have found z triangles".

例如在这种情况下,当程序比较第一行和第二行时,发现链接 1 2"存在,然后还写I have find 2 triangles"(因为每行都有数字 3 和 4).

For example in this case when the program compare the first row and the second row and find that "the link 1 2" exists and then write also "I have find 2 triangles" (because in each rows there are the numbers 3 and 4).

为此,我尝试编写以下程序:

For this purpose I have tried to write the following program:

use strict;
use warnings;
use diagnostics;
use Data::Dumper;

############ DATA ABSORTION

my $file = 'file.dat';
open my $fh, "<", $file or die "Cannot open $file: $!";

############ COLLECT THE DATAS IN A VECTOR as vector[i][j]

my @vector;

while (<$fh>) {

push @vector, [ split ];

}

############ START THE RESEARCH OF THE LINKS AND TRIANGLES BY MEANS OF FOR LOOPS

my @link;
my $triangles;

for (my $i=0 ; $i < scalar @vector; $i++){

$triangles=0;

for(my $j=0; $j < scalar @vector; $j++){

    for (my $k=$i+1; $k < scalar @vector; $k++){        

        for(my $l=0; $l < scalar @vector; $l++){

            if($vector[$i][0]==$vector[$k][$l] && $vector[$i][$j]==$vector[$k][0] && $l != 0 && $j != 0) {

                 @link=($vector[$i][0],$vector[$k][0]);

            print "I found the link @link\n";

                if($vector[$i][$j]==$vector[$k][$l] && $l != 0 && $j != 0 && $i != $k){

                $triangles++;


                }
            print "The number of triangles is $triangles\n\n";              
            }

        }
    }
  }
}

程序打印正确数量的链接,但我发现如果行数低于文件中的列数,程序不会读取整行,这可能是我的链接研究的问题.我认为问题出在 for 指令中的 scalar @vector 上限(但我不明白为什么).

The program print the right number of links but I found that if the number of rows is lower of the number of colums in the file, the program doesn't read the full row and this could be a problem for my link research. I think the problem is due at the scalar @vector upper limit in the for instrunctions (but I don't understand why).

第二个问题是它没有计算我正在寻找的三角形的正确数量...有帮助吗?

The second problem is that it does't count the right number o triangles that I'am looking for... Any helps?

推荐答案

该程序满足您的要求.此外,当找到一个三角形时,它会打印每个三角形的三个角.

This program does what you require. In addition it prints the three corners of each triangle when one is found.

use strict;
use warnings;
use 5.010;

my $filename = 'file.dat';
open my $fh, '<', $filename or die qq{Cannot open "$filename": $!};

my %vector;
while (<$fh>) {
  my @fields = split;
  my $root = shift @fields;
  $vector{$root} = { map { $_ => 1} @fields };
}
my @roots = sort { $a <=> $b } keys %vector;

for my $i (0 .. $#roots) {
  my $aa = $roots[$i];
  for my $j ($i + 1 .. $#roots) {
    my $bb = $roots[$j];
    next unless $vector{$aa}{$bb} and $vector{$bb}{$aa};

    say "I found the link $aa $bb";

    my $triangles = 0;
    for my $cc ( keys %{$vector{$aa}} ) {
      next if $cc == $aa or $cc == $bb;
      if ($vector{$bb}{$cc}) {
        say "Triangle $aa - $bb - $cc";
        $triangles++;
      }
    }
    say "I have found $triangles triangle". ($triangles == 1 ? '' : 's');
    print "\n";

  }
}

您显示的数据中只有两个三角形:1-2-3 和 1-2-4.遵循您的算法会导致该程序多次计算三角形,角的顺序不同.要将每个不同的三角形只计算一次,请更改线

There are only two triangles in the data you show: 1-2-3 and 1-2-4. Following your algorithm results in this program counting triangles more than once, with the corners in different orders. To count each distinct triangle only once, change the line

next if $cc == $aa or $cc == $bb;

next if $cc <= $aa or $cc <= $bb;

输出

I found the link 1 2
Triangle 1 - 2 - 4
Triangle 1 - 2 - 3
I have found 2 triangles

I found the link 1 3
Triangle 1 - 3 - 2
I have found 1 triangle

I found the link 1 4
Triangle 1 - 4 - 2
I have found 1 triangle

I found the link 2 3
Triangle 2 - 3 - 1
I have found 1 triangle

I found the link 2 4
Triangle 2 - 4 - 1
I have found 1 triangle

I found the link 2 5
I have found 0 triangles

I found the link 5 6
I have found 0 triangles

I found the link 5 7
I have found 0 triangles

I found the link 6 8
I have found 0 triangles

I found the link 7 8
I have found 0 triangles

I found the link 8 9
I have found 0 triangles

这篇关于文件行对抗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆