我正在尝试将以下字符集转换为相应的值,以获得fasta文件附带的质量得分:
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
它们的值应为0-93。因此,当我输入使用这些符号的fastq文件时,我想在质量得分文件中输出每个符号的数值。
我尝试使用split //将它们放入一个数组中,然后制作一个散列,其中每个键都是符号,值是它在数组中的位置:
for (my $i = 0; $i<length(@qual); $i++) {
print "i is $i, elem is $qual[$i]\n";
$hash{$qual[$i]} = $i;
我试过硬编码哈希:
my %hash = {"!"=>"0", "\""=>"1", "#"=>"2", "\$"=>"3"...
对于需要它们的特殊字符有和没有转义但似乎无法使其工作。 这只是输出:
.
.
.
i is 0, elem is !
i is 1, elem is "
i is 0, elem is !
i is 1, elem is "
i is 0, elem is !
i is 1, elem is "
" 1
Use of uninitialized value $hash{"HASH(0x100804ed0)"} in concatenation (.) or string at convert_fastq.pl line 24, <> line 40.
HASH(0x100804ed0)
! 0
有没有人有任何想法?我很感激帮助。
答案 0 :(得分:2)
或许从角色的ord
中减去33来产生你想要的值会有所帮助:
use strict;
use warnings;
my $string = q{!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~};
for ( split //, $string ) {
print "$_ = ", ord($_) - 33, "\n";
}
部分输出:
! = 0
" = 1
# = 2
$ = 3
% = 4
& = 5
' = 6
( = 7
) = 8
* = 9
+ = 10
...
这样,您不需要构建具有字符/值对的哈希,而只需使用$val = ord ($char) - 33;
来获取值。
答案 1 :(得分:2)
{ ... }
类似于
do { my %anon; %anon = ( ... ); \%anon }
所以当你做到了
my %hash = { ... };
您将一个项目分配给哈希(对哈希的引用),而不是您应该分配的键值列表。 Perl用以下内容警告过你:
Reference found where even-sized list expected
(你为什么不提这个?!)
您应该使用
my %decode_map = ( ... );
例如,
my %decode_map;
{
my $encoded = q{!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~};
my @encoded = split //, $encoded;
$decode_map{$encoded[$_]} = $_ for 0..$#encoded;
}
鉴于这些基本上是非空白可打印的ASCII字符,所以你可以简单地使用
my %decode_map = map { chr($_ + 0x21) => $_ } 0x21..0x7E;
这意味着您可以完全避免构建哈希,替换
my %decode_map = map { chr($_ + 0x21) => $_ } 0x21..0x7E;
die if !exists($decode_map{$c});
my $num = $decode_map{$c};
只是
die if ord($c) < 0x21 || ord($c) > 0x7E;
my $num = ord($c) - 0x21;
答案 2 :(得分:0)
从语言不可知的角度来看:使用一个包含256个条目的数组,每个ASCII字符一个。然后你可以在['!']存储0,在[''']存储1,依此类推。在解析输入时,你可以直接在该数组中查找char的索引。预先小心错误处理,你可以存储 - 1在所有无效字符中并在解析文件时检查它。