[精讚] [會員登入]
2431

[PERL] 11- 雜湊的範例

Perl 的幾個雜湊範例

分享此文連結 //n.sfs.tw/11695

分享連結 [PERL] 11- 雜湊的範例@新精讚
(文章歡迎轉載,務必尊重版權註明連結來源)
2019-10-22 22:13:23 最後編修
2017-08-25 00:25:58 By 張○○
 

自動目錄

上一篇寫到雜湊的基本性質和操作,PERL的雜湊就像奇蹟一樣的存在。這篇要說雜湊的二個範例。

範例一、計算文字出現次數

一段字串中,計算各字出現的次數,中英文一樣的運作原理,但中文字因為顯示的關係比較麻煩一點。

use utf8;
binmode(STDIN, ':encoding(utf8)');
binmode(STDOUT, ':encoding(utf8)');
binmode(STDERR, ':encoding(utf8)');

$text= <<"DOC";
石室詩士施氏,嗜獅,誓食十獅
施氏時時適市視獅
十時,適十獅適市
是時,適施氏適市
氏視是十獅,恃矢勢,使是十獅逝世
氏拾是十獅屍,適石室
石室濕,氏使侍拭石室
石室拭,氏始試食是十獅
食時,始識是十獅,實十石獅屍
試釋是事
DOC

%word=();
@words= split(//,$text);
foreach(@words){
  $word{$_}++;
}

while (($key, $value) = each(%word))
{
     print $key.", ".$value. "\n";
}

print "\n";

第1-4行 為了能正確顯示中文字須使用utf8編碼,參考[1],use是使用套件,在後面的篇章會說明。

第6行 還記得在 [PERL] 02-註解、變數和常數這篇裡有介紹過的HEREDOC,注意寫法,這首「施氏食獅史」裡面的字有出現的次數。

第19行 定義一個空的雜湊

第20行 在08-陣列 #2 --操作 有介紹過的split能用樣式把字串拆開,這裡使用空的樣式是一種技巧,能把字一個個拆開。

第21-23行 把每個字符都拿去當雜湊的「鍵」,這裡展現PERL優異的地方,就算是你中文字也是一樣可以當成鍵沒有問題。

第25-28行 傾印雜湊

結果

矢, 1
逝, 1
是, 7
世, 1
釋, 1
石, 6
試, 2
恃, 1
拭, 2
侍, 1
市, 3
士, 1
食, 3
,, 11
時, 5
誓, 1
獅, 10
氏, 7
識, 1

<這個是換行,但你看不見>
, 10
始, 2
施, 3
拾, 1
視, 2
濕, 1
事, 1
使, 2
實, 1
十, 9
室, 5
嗜, 1
詩, 1
屍, 2
勢, 1
適, 6

可以發現PERL連換行都會列入評估,你可以變換傾印的方式,例如排序出現的次數等等。這對PERL來說是很簡單的事。

 

範例二、將DNA序列轉成對映的胺基酸

這個範列在生物上可能會用到,把DNA的序列轉成對映的胺基酸,DNA的序列主要是由約TACG這四種鹼基三個三個排列組成約20種的胺基酸,我們拿到一串鹼基序列檔,要想辦法改為胺基酸序列。

鹼基序列檔有非常多種的形式,我取其中一種較常見的型式作範例。並用PERL優異的「程式彈性」,能創意的處理很多不好處理的字串。在下面的範例中,我先避開使用取代和比對,改用在前面提過的方法來解決問題,要先說這系統文章的範例全是我自己寫的,都不是去抄來的。

%aminos = qw(
TCA  S  TCC  S  TCG  S  TCT  S  TTC  F  TTT  F  TTA  L  TTG  L
TAC  Y  TAT  Y  TAA  _  TAG  _  TGC  C  TGT  C  TGA  _  TGG  W
CTA  L  CTC  L  CTG  L  CTT  L  CCA  P  CCC  P  CCG  P  CCT  P
CAC  H  CAT  H  CAA  Q  CAG  Q  CGA  R  CGC  R  CGG  R  CGT  R
ATA  I  ATC  I  ATT  I  ATG  M  ACA  T  ACC  T  ACG  T  ACT  T
AAC  N  AAT  N  AAA  K  AAG  K  AGC  S  AGT  S  AGA  R  AGG  R
GTA  V  GTC  V  GTG  V  GTT  V  GCA  A  GCC  A  GCG  A  GCT  A
GAC  D  GAT  D  GAA  E  GAG  E  GGA  G  GGC  G  GGG  G  GGT  G
);
$DNA = <<"DOC";

        1 TTGATTACCT TATTTGATCA TTACACATTG TACGCTTGTG TCAAAATATC ACATGTGCCT
       61 TATAAATGTG TACAACTATT AGTTATCCAT AAAAATTAAA AATTAAAAAA TCCGTAAAAT
      121 GGTTTAAGCA TTCAGCAGTG CTGATCTTTC TTAAATTATT TTTCTAATTT TGGAAAGAAA
      181 GCACAAAATC TTTGAATTCA CAATTGCTTA AAGACTGAGG TTAACTTGCC AGTGGCAGGC
      241 TTGAGAGATG AGAGAACTAA CGTCAGAGGA TAGATGGTTT CTTGTACAAA TAACACCCCC
      301 TTATGTATTG TTCTCCACCA CCCCCGCCCA AAAAGCTACT CGACCTATGA AACAAATCAC
      361 ACTATGAGCA CAGATAACCC CAGGCTTCAG GTCTGTAATC TGACTGTGGC CATCGGCAAC
      421 CAGAAATGAG TTTCTTTCTA ATCAGTCTTG CATCAGTCTC CAGTCATTCA TATAAAGGAG
      481 CCCGGGGATG GGAGGATTCG CATTGCTCTT CAGCACCAGG GTTCTGGACA GCGCCCCAAG
      541 CAGGCAGCTG ATCGCACGCC GCTTCCTCTC AATCTCCGCC AGCGCTGCTA CTGCCCCTCT
      601 AGTACCCCCT GCTGCAGAGA AAGAATATTA CACCGGGATC CATGCAGCCA GCAATGATGA
      661 TGTTTTCCAG TAAATACTGG GCACGGAGAG GGTTTTCCCT GGATTCAGCA GTGCCCGAAG
      721 AGCATCAGCT ACTTGGCAGC TCAC
DOC
@seg= split(/[\d\s]+/, $DNA);
$dna = join("", @seg);
@amino = unpack("(A3)*", $dna);
$idx=1;
foreach (@amino){
  die "不正確的序列在位置 $idx: $_" unless exists $aminos{$_};
  print $aminos{$_};
  $idx+=3;
}

第1-10行  用qw設定雜湊的方法,只要鍵和值依序排列即可

第11-26行 鹼基字串,最左邊的數字是字元位置,FASTA格式,取自[2]

第27行 把字串用樣式[\d\s]+拆成陣列,意思是只要是數字、空白、定位、換行都當成分隔,雖然這樣前面會多一個空白但不必理會。

第28行 用08-陣列 #2 --操作 介紹過的join函數,把陣列黏起來,分隔符號是空字串。

第29行 unpack函數在這是第一次用,主要目的是把內容(字串)依樣式作成小段。其樣版(template)是 (A3)*

   () 小刮號的內容組成一個群組
   A 代表任一個ASCII文字字元
   3 表示出現3次
   * 前面的樣版重覆解包

這個函數有點複雜,也許你可以用 substr 來達成一樣的功能

$i=0;
while( $_= substr($dna, $i, 3)){ #在第$i位置取3個字元
  push @amino, $_;
  $i+=3;
}

第32行 如果 $protein{$_}這個值不存在,代表是無效的DNA鹼基序,跳出程式。

結果

LITLFDHYTLYACVKISHVPYKCVQLLVIHKN_KLKNP_NGLSIQQC_SFLNYFSNFGKKAQNL_IHNCLKTEVNLPVAGLRDERTNVRG_MVSCTNNTPLCIVLHHPRPKSYSTYETNHTMSTDNPRLQVCNLTVAIGNQK_VSF_SVLHQSPVIHIKEPGDGRIRIALQHQGSGQRPKQAADRTPLPLNLRQRCYCPSSTPCCRERILHRDPCSQQ__CFPVNTGHGEGFPWIQQCPKSISYLAAH

以上二個範例大致上顯示了PERL的強大分析能力,無論字串是什麼格式,對PERL來設都有解決之道。

上一篇 10- 雜湊
回到目錄 01-撰寫第一隻PERL程式
下一篇 12- 副程式

參考資料

[1] https://blog.wu-boy.com/2009/07/perl-with-utf-8-mode/

[2] https://www.genomatix.de/online_help/help/sequence_formats.html

END

你可能感興趣的文章

[PERL] 05-運算子 #1 PERL的運算子介紹,總共有21種

[PERL] 23-多執行緒 而多執行緒的程式,可在一次執行程式時間,同時進行多線程的計算,在效率上可獲得即大的提升。

PERL一次讀取檔案所有內容的方法($/) perl可以使用slurp mode一次讀完檔案所有內容的方法及一些範例

[PERL] 17-參照 PERL的參照,就是指標

[PERL] 10- 雜湊 Perl 的hash 指標陣列

[PERL] 04-基本比對 perl的正規表達示基本比對

我有話要說

>>

限制:留言最高字數1000字。 限制:未登入訪客,每則留言間隔需超過10分鐘,每日最多5則留言。

訪客留言

[無留言]

隨機好文

沒有非誰做不可的事,也沒有不可被取代的人 沒有非誰做不可的事,也沒有不可被取代的人

談借錢 人借錢時手心向上頭向下,人還錢時手心向下頭向上

UTF-8 BOM (Byte Order Mark) 的問題 在 Michael Kaplan 那看到 Every character has a story #4: U+feff

Linux shell 的date表示法 linux下SHELL中的date表示法

維修冰箱 維修冰箱