1. 程式人生 > >習題3-7 DNA序列

習題3-7 DNA序列

題目描述:
輸入m個長度均為n的DNA序列,求一個DNA序列,到所有序列的總Hamming距離儘量小。 兩個等長字串的Hamming距離等於字元不同的位置個數,例如,ACGT和GCGA的Hamming距離為2(左數第1, 4個字元不同)。輸入整數m和n(4≤m≤50, 4≤n≤1000),以及m個長度為n的DNA序列(只包含字母A,C,G,T),輸出到m個序列的Hamming距和最小的DNA序列和對應的距離。 如有多解,要求為字典序最小的解。 例如,對於下面5個序列,最優為:TAAGATAC。
T A T G A T A C
T A A G C T A C
A A A G A T C C
T G A G A T A C
T A A G A T G T

思路:
用二維陣列儲存輸入,求總hamming距離最小,其實就是求最接近於每列元素的那個字母。例如第一列:
T T T A T T
顯然T是最接近的,因為這組裡T出現次數最多。
使用整型陣列a[4]儲存每列中四個元素各出現了多少次,那麼出現最多的也就是最接近的,直接輸出即可。

程式碼:

#include<iostream>
#include<string>
#include<cstring>
#include<ctype.h>
#define LOCAL
using namespace std;
void count(int mark[],char ch)
{
	switch(ch)
	{
		case 'A':mark[0]++;break;
		case 'C':mark[1]++;break;
		case 'G':mark[2]++;break;
		default: mark[3]++;break;
	}
}
int main()
{
	char a[52][1002],ans[4]={'A','C','G','T'};
	int i,j,mark[5],max,pos,m,n,sum=0;
	cin>>m>>n;
#ifndef LOCAL
	freopen("data.in","r",stdin);
	freopen("data.out","w",stdout);
#endif
	for(i=0;i<m;i++)
		scanf("%s",a[i]);
	for(j=0;j<n;j++)
	{
		memset(mark,0,sizeof(mark));
		max=-1;
		for(i=0;i<m;i++)
			count(mark,a[i][j]);
		for(i=0;i<4;i++)
			if(mark[i]>max){
				max=mark[i];
				pos=i;
			}
		sum+=m-max;
		cout<<ans[pos];
	}
	cout<<endl<<sum;
	return 0;
}