基因資料壓縮演算法(ACTG) C++
阿新 • • 發佈:2019-01-04
基因資料壓縮演算法是一個初級的資料壓縮演算法,基因資料如下所示"ATAGATGCAT",如果使用標準的ASCII編碼(每個字元1個位元組),這個基因字串的流長度是10*8=80位。
這些字元是由4種不同的字元組成,所有我們可以使用雙位編碼壓縮,比如 A:00, C:01, T:10, G11,壓縮之後我們就可以在一個位元組存放4個基因字元了,當資料比較大時,壓縮效率為25%。
完整程式碼
輸出結果為:#include <iostream> #include <string> using namespace std; void PrintBits(const char *pstr, int width = 1); // ACTG A:00, C:01, T:10, G11 class Dna { public: Dna() : sizes(0) {} Dna(const char *str); void AddCompress(const char c) { Compress(c); } void AddCompress(const char *pstr); string Expand(); int Size() const { return sizes; } string Data() const { return data; } string Compress() const { return compressData; } void PrintCompressData() { PrintBits(compressData.c_str()); } void PrintCompressData(int width) { PrintBits(compressData.c_str(), width); } private: int sizes; // 存放資料數 string data; // 存放原始資料 string compressData; // 存放壓縮後的二進位制資料 void Compress(const char c); unsigned char Index(char c); char Table(int index) const; void PrintBits(const char c); void PrintBits(const char *pstr, int width = 1); }; int main(void) { char str[] = "ACTG"; Dna dna(str); cout << dna.Size() << endl; cout << dna.Expand() << endl; dna.AddCompress("GTCA"); cout << dna.Size() << endl; cout << dna.Expand() << endl; dna.PrintCompressData(); system("pause"); return 0; } Dna::Dna(const char *str) : sizes(0) { if (str) { const char *p = str; while (*p) { Compress(*p); p++; } } } void Dna::AddCompress(const char *pstr) { if (!pstr) return; const char *p = pstr; while (*p) { Compress(*p); p++; } } // class Dna private scope // 壓縮字元c,並新增到compressData中 void Dna::Compress(const char c) { data.append(1, c); if (sizes % 4 == 0) compressData.append(1, '\0'); int n = sizes % 4; compressData[sizes / 4] |= Index(c) << (6 - 2 * n); sizes++; } // 解壓縮,並以string返回 string Dna::Expand() { string s; for (int i = 0; i < sizes; i++) { int n = i % 4; unsigned char index = ((unsigned char)compressData[i / 4]) >> (6 - 2 * n); s.append(1, Table(index)); } return s; } // 根據char值返回對應的索引,比如'A'為0時返回0 unsigned char Dna::Index(char c) { if (c == 'A') return 0; else if (c == 'C') return 1; else if(c == 'T') return 2; else // if(c == 'G') return 3; } // 根據index值返回對應的字元,比如index為0時返回'A' char Dna::Table(int index) const { static char table[4] = { 'A', 'C', 'T', 'G' }; return table[index % 4]; } void Dna::PrintBits(const char c) { for (int i = 0; i < 8; i++) { if ((c << i) & 0x80) cout << '1'; else cout << '0'; } } void Dna::PrintBits(const char *pstr, int width) { if (!pstr) return; const char *p = pstr; int nums = 0; while (*p) { PrintBits(*p); p++; if (!((++nums) % width)) cout << endl; } cout << endl; }
參考:
《演算法》 第四版 5.5 資料壓縮