如果我在文本文件中得到一个表格,例如

  • 甲乙1
  • 碳2
  • 公元1
  • 巴3
  • 光盘2
  • 埃1
  • ED 2
  • CB2
  • . . .
  • . . .
  • . . .

我在另一个文本文件中得到了另一个符号列表。我想将该表转换为 Perl 数据结构,例如:

  • _阿德。。。
  • A 0 1 1 。。。
  • D 1 0 2 。。。
  • E 1 2 0 。。。
  • . . . . . . .

但我只需要一些选定的符号,例如在符号文本中选择了 A、D 和 E,但没有选择 B 和 C。

有帮助吗?

解决方案

第一个使用数组,第二个使用二维哈希。第一个应该大致如下所示:

$list[0] # row 1 - the value is "A B 1"

哈希值如下:

$hash{A}{A} # the intersection of A and A - the value is 0

对我来说,弄清楚如何实现一个问题大约占了 75% 的心理战时间。我不会详细讨论如何打印哈希或数组,因为这很简单,而且我也不完全清楚您希望如何打印它或您想要打印多少。但是将数组转换为散列应该看起来有点像这样:

foreach (@list) {
  my ($letter1, $letter2, $value) = split(/ /);
  $hash{$letter1}{$letter2} = $value;
}

至少,我认为这就是您正在寻找的。如果你 真的 希望您可以使用正则表达式,但这对于仅从字符串中提取 3 个值来说可能有点过大了。

编辑:当然,你也可以放弃 @list 并直接从文件中组装哈希值。但这是你的工作,而不是我的。

其他提示

你可以用 awk 尝试一下:

awk -f 矩阵.awk yourfile.txt > newfile.matrix.txt

其中matrix.awk是:

BEGIN {
   OFS="\t"
}
{
  row[$1,$2]=$3
  if (!($2 in f2)) { header=(header)?header OFS $2:$2;f2[$2]}
  if (col1[c]!=$1)
     col1[++c]=$1
}
END {
  printf("%*s%s\n", length(col1[1])+2, " ",header)
  ncol=split(header,colA,OFS)
  for(i=1;i<=c;i++) {
    printf("%s", col1[i])
    for(j=1;j<=ncol;j++)
      printf("%s%s%c", OFS, row[col1[i],colA[j]], (j==ncol)?ORS:"")
  }
}

另一种方法是创建一个二维数组 -

my @fArray = ();
## Set the 0,0th element to "_"
push @{$fArray[0]}, '_';

## Assuming that the first line is the range of characters to skip, e.g. BC
chomp(my $skipExpr = <>);

while(<>) {
    my ($xVar, $yVar, $val) = split;

    ## Skip this line if expression matches
    next if (/$skipExpr/);

    ## Check if these elements have already been added in your array
    checkExists($xVar);
    checkExists($yVar);

    ## Find their position 
    for my $i (1..$#fArray) {
        $xPos = $i if ($fArray[0][$i] eq $xVar);
        $yPos = $i if ($fArray[0][$i] eq $yVar);
    }

    ## Set the value 
    $fArray[$xPos][$yPos] = $fArray[$yPos][$xPos] = $val;
}

## Print array
for my $i (0..$#fArray) {
    for my $j (0..$#{$fArray[$i]}) {
        print "$fArray[$i][$j]", " ";
    }
    print "\n";
}

sub checkExists {
    ## Checks if the corresponding array element exists,
    ## else creates and initialises it.
    my $nElem = shift;
    my $found;

    $found = ($_ eq $nElem ? 1 : 0) for ( @{fArray[0]} );

    if( $found == 0 ) {
        ## Create its corresponding column
        push @{fArray[0]}, $nElem;

        ## and row entry.
        push @fArray, [$nElem];

        ## Get its array index
        my $newIndex = $#fArray;

        ## Initialise its corresponding column and rows with '_'
        ## this is done to enable easy output when printing the array
        for my $i (1..$#fArray) {
            $fArray[$newIndex][$i] = $fArray[$i][$newIndex] = '_';
        }

        ## Set the intersection cell value to 0
        $fArray[$newIndex][$newIndex] = 0;
    }
}

我对我处理参考文献的方式并不太自豪,但请容忍初学者(请在评论中留下您的建议/更改)。上面提到的 Chris 的哈希方法听起来容易多了(更不用说打字少了很多)。

CPAN 有很多 潜在有用的东西. 。我用 数据::表 出于多种目的。 数据::枢轴 看起来也很有前途,但我从未使用过它。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top