您的位置:首页 > 编程语言 > C语言/C++

基因数据压缩算法(ACTG) C++

2015-09-14 16:14 645 查看
基因数据压缩算法是一个初级的数据压缩算法,基因数据如下所示"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 数据压缩
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: