UVa1368 DNA Consensus String

来源:互联网 发布:淘宝购物车东西没了 编辑:程序博客网 时间:2024/06/08 07:23

《算法竞赛入门经典(第2版)》 作者:刘汝佳 

第三章习题3-7输入m个DNA序列,求一个DNA序列,与各序列的海明距离总和最小。

https://uva.onlinejudge.org//index.php?option=com_onlinejudge&Itemid=8&category=827

--------------------------------------E3-7.cpp--------------------------------------

#include <stdio.h>
#include <string.h>
#define LOCAL
#define maxm 51
#define maxn 1001


char str[maxn][maxm];


//输入一列的所有字符,找到其中出现次数最多的字母,如果有相等情况,返回字典顺序在前的字母 
char maxchar(char* a, int m)
{
int count[4];
memset(count, 0, sizeof(count));
for(int i = 0; i < m; i++)
switch(a[i]){
case 'A': count[0]++; break;
case 'C': count[1]++; break;
case 'G': count[2]++; break;
case 'T': count[3]++; break;
}
int temp = 0;
for(int i = 1; i < 4; i++)
if(count[temp] < count[i]) temp = i;
char ch;
switch(temp){
case 0: ch = 'A'; break;
case 1: ch = 'C'; break;
case 2: ch = 'G'; break;
case 3: ch = 'T'; break;
}
return ch;
}


//比较两个字符串a和b,统计其海明距离 
int cmp(char*a, char*b, int size)
{
int count = 0;
for(int i = 0; i < size; i++)
if(a[i] != b[i]) count++;
return count;
}


int main()
{
#ifdef LOCAL
freopen("E3-7.in", "r", stdin);
#endif
int kase, m, n;
scanf("%d", &kase);
while(kase--){
scanf("%d%d", &m, &n);
for(int i = 0; i < m; i++) {
char s[n];
scanf("%s", s);
for(int j = 0; j < n; j++)
str[j][i] = s[j];//将输入字符串数组转置,令str的每一行为原数组的每一列,便于统计每个字母出现次数 
}
char res[n+1];//******为了printf中输出字符串,需要在res末尾添加字符串结束标志 0 ****** 
for(int j = 0; j < n; j++){
res[j] = maxchar(str[j], m);//生成结果字符串 
}
res[n] = 0;
printf("%s\n", res);
int HammingDi = 0;
for(int i = 0; i < m; i++){
char s[n];
for(int j = 0; j < n; j++)
s[j] = str[j][i];//还得将字符串数组转置回来,或者空间换时间,设置两个数组 
HammingDi += cmp(res, s, n);//计算结果字符串res与每个字符串的海明距离总和 
}
printf("%d\n", HammingDi);
}
return 0;
}

-----------------------------------E3-7.in的分界线-------------------------------------


5 8 
TATGATAC
TAAGCTAC 
AAAGATCC 
TGAGATAC 
TAAGATGT 
4 10 
ACGTACGTAC 
CCGTACGTAG 
GCGTACGTAT 
TCGTACGTAA 
6 10 
ATGTTACCAT 
AAGTTACGAT 
AACAAAGCAA 
AAGTTACCTT 
AAGTTACCAA 
TACTTACCAA

0 0
原创粉丝点击