[精讚] [會員登入]
2527

[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] 06-運算子 #2 PERL的運算子介紹,總共有21種

[PERL] 常態分配亂數產生函數 一般而言我們使用程式內建的 rand 函數取得的亂數是平均分配的,但如果需要常態分配的亂數產生器該怎麼做?

[PERL] 01-撰寫第一隻PERL程式及目錄 PERL的系列教學文,適合有其他程式經驗但沒學過PERL的人

[PERL] 簡易檢查網頁記錄檔ip來源統計 利用PERL來檢查網頁記錄檔ip來源統計的簡易程式

[PERL]] find 和 perl 的結合--大量檔案中文字的取代 利用PERL作大量的文件取代

自行撰寫syslog server建立資訊安全控管中心#2 -- 架構和作法 利用PERL將syslog收攏到資料庫的程式,架構和作法

我有話要說

>>

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

訪客留言

[無留言]

隨機好文

安裝SPHINX支援中文 新版本的 sphinx 和舊版不同,網路上很多範例和教學是不能用的。此文是安裝和設定方法分享

[Centos6] 安裝wordpress Centos 6下安裝wordpress,非常簡單

我的便利帶變垃圾袋--談預付制 預付制說穿了,就是對賣家極有利,對買家極小利的消費經營模式。

銷售的困難點--庫存 銷售時,商人加上自己的利潤和風險,作為商品的售價,進貨面臨的問題會是什麼?

[CodeIgniter 3] 自寫找不到頁面(page404)的方法 使用CI3框架中如果找不到頁面,就會導到一個自定的404頁面,該怎麼做?