3

ユーザーから入力ファイルを受け取るプログラムを書いています。ファイルには多数の数値が含まれており、ファイル内の数値を読み取り、 GD::Graphを使用してそれらの数値に基づいてプロットを作成します。

ファイルの 1 行目は X 軸で、ファイルの 2 行目は X 軸に対応する Y 値で、3 行目、4 行目、... などです。例:

1 2 3 4 5 
2 4 5 10 14
5 6 8 12 13

したがって、上記では、最初の行は x 軸、2 番目の行は x 軸に対応する y 値であるため、10 ポイントが取得されます。(1, 2) (1, 5) (2, 4) (2, 6)....(4,10) (4,12) (5,14) (5, 13)

配列の各行を読み取ってから、スペースまたはタブで行を分割し、値を配列に格納する予定です。したがって、配列 1 には x 軸があり、配列 2 には y 軸がありますが、3、4、5、...、などの行を配列に格納して (x、y) になるようにするにはどうすればよいですか?

さらに、X 軸と Y 軸の制限を作成できるように、1 行目と 2 行目 (2 つの配列) の最大値を見つけるにはどうすればよいですか?

4

3 に答える 3

2

あなたの質問に対する答えではありませんが、GD::Graph::Dataをお見逃しなく。

各行の最初と最後が最小/最大であることが確実でない限り、 List::Utilmin()andのようなものを使用する必要がありますmax()


「ファイルの 1 行目は X 軸、ファイルの 2 行目は Y 軸、3 行目、4 行目、... などは X 軸に対応する点」という意味がよくわかりません。

于 2009-04-03T16:11:40.037 に答える
1

x 配列と y 配列は、必要に応じて拡張できます。

#!/usr/bin/perl

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

my @xs = ();
my @ys = ();
my $expecting_xs = 1;
my $last_xs_count;

while(<>) {
  chomp;
  my @values = split(/\s+/);
  if($expecting_xs) {
    push(@xs, @values);
    $last_xs_count = @values;
    $expecting_xs = 0;
  } else {
    if(@values != $last_xs_count) {
      die "Count mismatch";
    } 
    push(@ys, @values);
    $expecting_xs = 1;
  }
}

if(!$expecting_xs) {
  die("Odd number of lines");
}

my($xmin, $xmax) = extremes(@xs);
my($ymin, $ymax) = extremes(@ys);

print "xmin: $xmin xmax: $xmax ymin: $ymin ymax: $ymax\n";
print Dumper(\@xs), Dumper(\@ys);

sub extremes {
  my(@values) = @_;
  return undef unless @values;
  my $min = shift(@values);
  my $max = $min;
  for my $value (@values) {
    $max = $value if $value > $max;
    $min = $value if $value < $min;
  }
  return $min, $max;
}
于 2009-04-03T17:47:30.760 に答える
0

おっと、質問を読み間違えました。最初の線の後の各線が線を表すか、すべてがプロットされる点に応じて、AoAoHまたはAoHのいずれかが必要です。ファイルの各行がグラフの行になる場合、次のように記述します。

#!/usr/bin/perl

use strict;
use warnings;
use List::Util qw/min max/;

my @x_points         = split " ", scalar <>; #read in the x axis labels
my ($x_min, $x_max)  = (sort { $a <=> $b } @x_points)[0,-1];
my ($y_min, $y_max)  = (0, 0);

#lines is an AoAoH, first layer are the lines to be drawn
#second layer is a list of coords
#third layer are the x and y coords
my @lines;
while (<>) {
    my @y_points = split;
    #if the two arrays are not the same size, we have a problem
    die "invalid file\n" unless @y_points == @x_points;

    $y_min = max($y_min, @y_points);
    $y_max = min($y_max, @y_points);

    push @lines, [ 
        map { { x => $x_points[$_], y => $y_points[$_] } }  
    0 .. $#x_points 
    ];
}

use Data::Dumper;

print "x min and max $x_min $x_max\n",
      "y min and max $y_min $y_max\n",
      "data:\n",
      Dumper(\@lines);

my $i;
for my $line (@lines) {
    $i++;
    print "line $i is made up of points: ",
        (map { "($_->{x}, $_->{y}) " } @$line), "\n";
}

そして、それらがプロットされるポイントにすぎない場合、これをどのように処理するかを次に示します。

#!/usr/bin/perl

use strict;
use warnings;
use List::Util qw/min max/;

my @x_points         = split " ", scalar <>; #read in the x axis labels
my ($x_min, $x_max)  = (sort { $a <=> $b } @x_points)[0,-1];
my ($y_min, $y_max)  = (0, 0);

#lines is an AoAoH, first layer are the lines to be drawn
#second layer is a list of coords
#third layer are the x and y coords
my @points;
while (<>) {
    my @y_points = split;
    #if the two arrays are not the same size, we have a problem
    die "invalid file\n" unless @y_points == @x_points;

    $y_min = max($y_min, @y_points);
    $y_max = min($y_max, @y_points);

    push @points,
        map { { x => $x_points[$_], y => $y_points[$_] } }
        0 .. $#x_points;
}

use Data::Dumper;

print "x min and max $x_min $x_max\n",
      "y min and max $y_min $y_max\n",
      "data:\n",
      Dumper(\@points);

print "Here are the points: ", 
    (map { "($_->{x}, $_->{y}) " } @points), "\n";
于 2009-04-03T16:02:43.350 に答える