根据二进制数创建单词列表

根据二进制数创建单词列表

我有一个如下所示的矩阵:

输入

A   B   C   D   E   F   G   H   I 
0   0   0   0   1   0   0   0   1
0   0   0   1   0   0   0   0   0  
0   0   0   1   0   0   0   0   0  
1   0   0   0   0   0   0   0   0  
1   0   1   0   0   0   1   0   0  
1   0   0   1   0   0   0   1   0  
1   0   0   0   1   1   1   0   0  

我想为每一行提取与值 1 对应的字母列表。

输出

E,I 
D
D
A
A,C,G  
A,D,H  
A,E,F,G  

我尝试拆分标题并将单词与数字匹配,但失败了。

答案1

awk

NR == 1 { for(column=1; column <= NF; column++) values[column]=$column; }
NR > 1 { output=""
        for(column=1; column <= NF; column++)
                if($column) output=output ? output "," values[column] : values[column]
        print output }

答案2

另一张与perl

$ perl -lane 'if($. == 1){ @h=@F }
              else{@i = grep {$F[$_]==1} (0..$#F); print join ",",@h[@i]}
             ' ip.txt
E,I
D
D
A
A,C,G
A,D,H
A,E,F,G
  • -a在空格上分割输入行的选项,可在@F数组中使用
  • if($. == 1){ @h=@F }如果第一行保存标题
  • @i = grep {$F[$_]==1} (0..$#F)如果条目是则保存索引1
  • print join ",",@h[@i],使用作为分隔符仅打印标头数组中的那些索引

答案3

仍然为了好玩,有一个zsh版本:

{
   read -A a  &&
   while read -A b; do
     echo ${(j<,>)${(s<>)${(j<>)a:^b}//(?0|1)}}
   done
} < file
  • ${a:^b} 拉链两个数组,所以你得到 A 0 B 0 C 0 D 0 E 1 F 0 G 0 H 0 I 1
  • ${(j<>)...}连接元素之间没有任何中间内容,因此它变为 A0B0C0D0E1F0G0H0I1
  • ${...//(?0|1)}我们从中去掉?0and 1,这样它就变成了 EI:
  • ${(s<>)...}不进行任何分割以获得每个字母一个元素的数组:EI
  • ${(j<,>)...}加入,-> E,I 的人。

答案4

下面是 Perl 的解决方案:

use strict;

my @header = split /\s+/, <>;
<>; ## Skip blank line
while (<>) {
    my @flags = split /\s+/;
    my @letters = ();
    for my $i (0 .. scalar @flags - 1) {
        push @letters, $header[$i] if $flags[$i];
    }

    print join(',', @letters), "\n";
}

它的工作原理是,将标题列读入数组,然后,对于每个数据行,如果匹配的数据列计算结果为 true,则将列名称复制到输出数组。然后以逗号分隔打印列名称。

相关内容