in reply to create a matrix for print 0 or 1 from pairing

TIMTOWTDI, with a HoH... to get you started... though you might get problems with extremely large numbers of Ax;Ay relationships. Then, try to use bitmaps or a DB.
HTH

use strict; use warnings; my %A; my ($max_row, $max_col) = (4,4); # autovivify interesting rows/cols of %A while (<DATA>) { warn("Line $.: cannot understand: $_") , next unless /A(\d+);A(\d+)/ +; my ($row, $col) = ($1,$2); $A{$row}{$col}++; $A{$col}{$row}++; # uncomment if relationship is not bidirectional } # print col. header print " "; printf("A%-3d",$_) for (1..$max_col); print "\n"; #print matrix A for my $row (1 .. $max_row) { printf("A%-3d", $row); for my $col (1 .. $max_col) { printf(" %-3d", exists $A{$row}{$col} ? "1" : "0" ); } print "\n"; } __DATA__ A1;A4 A2;A3 A2;A4 A1;A3
Output:
A1 A2 A3 A4 A1 0 0 1 1 A2 0 0 1 1 A3 1 1 0 0 A4 1 1 0 0
Update: After OP clarified, that A1..A# are actually strings, here are some suggestions to modify the code above: Update2: Example plus annotations added.
use strict; use warnings; my %A; # remembers pairing (x,y) as $A{x}{y} and $A{y}{x} my @order; # set output order here or trust auto-generated @order be +low # e.g. @order = qw(eel horse lion mule tiger); # autovivify interesting pairings while (<DATA>) { warn("Line $.: cannot understand: $_") , next unless /(\w+);(\w+)/; my ($row, $col) = ($1,$2); $A{$row}{$col}++; # ++ just triggers the autovivification (see: perl +ref) $A{$col}{$row}++; # uncomment line if relationship is not bidirectio +nal # ... would break gimmick#1 } # Gimmick #1: auto-generated list-order when list-order was not given # assumption: symmetric relationship -> square matrix; # combinations never paired are filtered out - bug or feat +ure? @order = sort keys %A unless @order; # create order unless given above # Gimmick #2: fixed auto-width for output (min. width: 2+3 ('###')) my $width = 2 + (sort { $a <=> $b } ( map { length $_ } (@order, '### +' )) )[-1]; my $format = '%-' . $width . 's'; # printf()-format for fixed width c +olumns # print header printf($format, $_) for ( " ", @order ); print "\n"; # print matrix A for my $row (@order) { printf($format, $row); for my $col (@order) { printf($format, exists $A{$row}{$col} ? "1" : "0"); # Idea for gimmick#3: $format = f( column ) } print "\n"; } __DATA__ horse;tiger lion;mule lion;tiger horse;mule

Replies are listed 'Best First'.
Re^2: create a matrix for print 0 or 1 from pairing
by vis1982 (Acolyte) on Oct 28, 2009 at 16:48 UTC
    Thanks vey much
    If u have horse instead of A1 lion instead of A2 mule instead of A3 tiger instead of A4
    __DATA__ horse;tiger lion;mule lion;tiger horse;mule
    Then in respone to that code tried to modify.
    use strict; use warnings; my %A; my ($max_row, $max_col) = (4,4); # autovivify interesting rows/cols of %A while (<DATA>) { warn("Line $.: cannot understand: $_") , next unless /(\w+);(\w+)/ +; my ($row, $col) = ($1,$2); $A{$row}{$col}++; $A{$col}{$row}++; # uncomment if relationship is not bidirectional } # print col. header print " "; printf("%-3d",$_) for (1..$max_col); print "\n"; #print matrix A for my $row (1 .. $max_row) { printf("%-3d", $row); for my $col (1 .. $max_col) { printf(" %-3d", exists $A{$row}{$col} ? "1" : "0" ); } print "\n"; }
    printing as 1 2 3 4 1 0 0 0 0 2 0 0 0 0 3 0 0 0 0 4 0 0 0 0
    output shud be like
    horse lion mule tiger horse 0 0 1 1 lion 0 0 1 1 mule 1 1 0 0 tiger 1 1 0 0
      Thanks

      I have tried using that as per suggestions by Perlbotics /p>

      #use strict; use warnings; my %A = (horse=> 'a',lion=>'b' ,mule=>'c',tiger =>'d'); my @order= sort keys %A; while (<DATA>) { warn("Line $.: cannot understand: $_") , next unless /(\w+);(\w+)/; my ($row, $col) = ($1,$2); $A {$row}{$col}++; $A{$col}{$row}++; } # print col. header print " "; printf(" %2s",$_) for (@order); print "\n"; #print matrix A for my $row (@order) { printf(" %2s", $row); for my $col (@order) { printf(" %3d", exists $A{$row}{$col} ? "1" : "0" ); } print "\n"; } __DATA__ horse;tiger lion;mule lion;tiger horse;mule
      I have got ouput horse lion mule tiger horse 0 0 1 1 lion 0 0 1 1 mule 1 1 0 0 tiger 1 1 0 0
      However If u see in the code i have not use strict command; if using strict command in the first line error displayed will be Can't use string ("a") as a HASH ref while "strict refs" in use at work_matrix.pl line 12, <DATA> line 1.

      What can be possible solution if using strict command?

        change lines 5+6 to my %A; my @order=qw/horse lion mule tiger/;

        Keywords to check are: soft references and auto-vivification: your strings 'a' to 'd' can be abused as soft references, which happens without use strict. With use strict however, you need a real hash-ref in the elements of %A instead - see perlreftut for more on references and soft references. Or omit the initialization of your hash-of-hashes %A to autovivify any undef values automagically as required (Autovivify definition or again: perlreftut).

        and for your aligning your table layout, consider something like sprintf "%5s", $stringvariable

        cu & HTH, Peter -- hints may be untested unless stated otherwise; use with caution & understanding.