PHP - 处理大量数字而不存储它们
PHP - Manipulate large numbers without store them
我正在尝试解决 rosalind.info 的生物信息学问题,但我被这个问题拒之门外:http://rosalind.info/problems/mrna/
要解决这个问题,您必须计算可以翻译蛋白质的不同 RNA 串的数量,以 1,000,000 为模。
生物学背景:一个protein is a string composed of 20 amino acids represented with 20 different letters. Each amino acids can be replaced with more than one RNA字符串(由3个字母各1组成)。
这个问题让您了解如何在编程时管理大数,这在生物信息学中很常见。我尝试了不同的方法,但我总是得到 INF 或负值,所以我做错了。
这些问题本身表明我应该找到一种无需存储即可处理大量数字的方法。这怎么可能?我怎样才能用 PHP 实现它?
这是我迄今为止最好的成绩:
<?php function protein_reverse($sec) {
$sec_arr = str_split($sec);
$aa = array(
'F' => '2',
'L' => '6',
'S' => '6',
'Y' => '2',
'C' => '2',
'W' => '1',
'P' => '4',
'H' => '2',
'Q' => '2',
'R' => '4',
'I' => '3',
'M' => '1',
'T' => '4',
'N' => '2',
'K' => '2',
'V' => '4',
'A' => '4',
'D' => '2',
'E' => '2',
'G' => '4',
);
$r = 1;
foreach ( $sec_arr as $base ) {
$r *= $aa[$base] % 1000000;
}
return $r;
} ?>
我终于能够解决问题了。首先,就像@Gavriel 在评论中添加的问题一样,我不得不使用 GMP 库来进行这些大数字操作。其次,最后我错过了每 3 个乘法。这是必要的,因为如果蛋白质完成,则必须有一个终止密码子 (secuence)。
/*
Reverse translation of protein
@return number of possible RNA strings modulo 1000000
*/
function protein_reverse($sec) {
$sec_arr = str_split($sec);
$aa = array(
'F' => '2',
'L' => '6',
'S' => '6',
'Y' => '2',
'C' => '2',
'W' => '1',
'P' => '4',
'H' => '2',
'Q' => '2',
'R' => '6',
'I' => '3',
'M' => '1',
'T' => '4',
'N' => '2',
'K' => '2',
'V' => '4',
'A' => '4',
'D' => '2',
'E' => '2',
'G' => '4',
);
$r = 1;
foreach ( $sec_arr as $base ) {
$r = gmp_mul($r, $aa[$base]);
}
$r = gmp_mul($r, 3);
$r = gmp_mod($r, 1000000);
return $r;
}
我正在尝试解决 rosalind.info 的生物信息学问题,但我被这个问题拒之门外:http://rosalind.info/problems/mrna/
要解决这个问题,您必须计算可以翻译蛋白质的不同 RNA 串的数量,以 1,000,000 为模。
生物学背景:一个protein is a string composed of 20 amino acids represented with 20 different letters. Each amino acids can be replaced with more than one RNA字符串(由3个字母各1组成)。
这个问题让您了解如何在编程时管理大数,这在生物信息学中很常见。我尝试了不同的方法,但我总是得到 INF 或负值,所以我做错了。
这些问题本身表明我应该找到一种无需存储即可处理大量数字的方法。这怎么可能?我怎样才能用 PHP 实现它?
这是我迄今为止最好的成绩:
<?php function protein_reverse($sec) {
$sec_arr = str_split($sec);
$aa = array(
'F' => '2',
'L' => '6',
'S' => '6',
'Y' => '2',
'C' => '2',
'W' => '1',
'P' => '4',
'H' => '2',
'Q' => '2',
'R' => '4',
'I' => '3',
'M' => '1',
'T' => '4',
'N' => '2',
'K' => '2',
'V' => '4',
'A' => '4',
'D' => '2',
'E' => '2',
'G' => '4',
);
$r = 1;
foreach ( $sec_arr as $base ) {
$r *= $aa[$base] % 1000000;
}
return $r;
} ?>
我终于能够解决问题了。首先,就像@Gavriel 在评论中添加的问题一样,我不得不使用 GMP 库来进行这些大数字操作。其次,最后我错过了每 3 个乘法。这是必要的,因为如果蛋白质完成,则必须有一个终止密码子 (secuence)。
/*
Reverse translation of protein
@return number of possible RNA strings modulo 1000000
*/
function protein_reverse($sec) {
$sec_arr = str_split($sec);
$aa = array(
'F' => '2',
'L' => '6',
'S' => '6',
'Y' => '2',
'C' => '2',
'W' => '1',
'P' => '4',
'H' => '2',
'Q' => '2',
'R' => '6',
'I' => '3',
'M' => '1',
'T' => '4',
'N' => '2',
'K' => '2',
'V' => '4',
'A' => '4',
'D' => '2',
'E' => '2',
'G' => '4',
);
$r = 1;
foreach ( $sec_arr as $base ) {
$r = gmp_mul($r, $aa[$base]);
}
$r = gmp_mul($r, 3);
$r = gmp_mod($r, 1000000);
return $r;
}