您的位置:首页 > 其它

UVa 1368 DNA Consensus String

2017-02-27 22:45 309 查看

1368 DNA Consensus String

要弄明白的

Hamming distance

就是不相同的个数。

一列一列的看,选重复最多的那个。

统计字符出现次数?

计数器

把多个变量存入一个字符串

直接创建一个大空间的字符串,for循环赋值。

字典最小

问题的本质是,一列中如果最多出现次数的字母 有多个,那么取最小的那个就能保证字典最小。在判断的时候,将ACGT从大到小排。

总结

buf未清空的问题

在程序中我们这样做:

#define maxn 1001
int main()
{
char buf[max]
}


创建一个比题目给定空间大的maxn,保证空间够用。然后进行如下操作:

for()
{
int buf[maxn]; //
for()
{
//对buf赋值
}
}


外层for循环进行第二次的时间,buf第一次被赋的值 不会被清除。所以容易产生问题。使用的时候一定要保证正确的buf大小。

例如第一次给buf赋值为1,2,3,4,5

buf = {1, 2, 3, 4, 5,...}


第二次赋值为1,2,3,4,那么此时的buf为:

buf = {1, 2, 3, 4, 5, ....}


5依然存在。如果第二次用错了buf的大小,那么容易产生错误的结果。所以这个预先声明大空间的方法使用简单,但也空间出错。我在做题的过程中写的getMore函数,使用了strlen来得到它的长,就会出现上面的问题,这里应该直接指定s的大小,不然如果出来多余的字符就会有问题。

mycode

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

//获取出现最多字符的位置和出现个数
int getMore(char *s, int slen, char &resCh, int &num)
{
int location[4]; //A,C,G,T出现个数
char res[4] = {'A', 'C', 'G', 'T'}; //方便返回字符,从小到大排保证字典最小
memset(location, 0, sizeof(location));
//int len = strlen(s);
for (int i = 0; i < slen; i++)
{
if (s[i] == 'A')
{
location[0]++;
}
if (s[i] == 'C')
{
location[1]++;
}
if (s[i] == 'G')
{
location[2]++;
}
if (s[i] == 'T')
{
location[3]++;
}
}
int locMore = 0;
for (int i = 0; i < 3; i++)
{
if (location[locMore] < location[i + 1])
{
locMore = i + 1;
}
}
resCh = res[locMore];
num = location[locMore];
return locMore;
}
int main()
{
int T;
scanf("%d", &T);
for (int i = 0; i < T; i++)
{
int m, n;
scanf("%d%d", &m, &n);
char s[maxm][maxn]; //输入的字符串
char res[maxn]; //返回结果字符串
for (int im = 0; im < m; im++)
{
scanf("%s", s[im]);
}

int hamming = 0;
for (int in = 0; in < n; in++)
{
char buf[maxm];
for (int im = 0; im < m; im++)
{
//把多个变量存入一个字符串
buf[im] = s[im][in];
}
char locMore;
int num=0;

getMore(buf, m, locMore, num); //获取出现次数最多的字符并得到出现次数
hamming += m - num;
res[in] = locMore;

}
for (int j = 0; j < n; j++)
{
putchar(res[j]);
}
printf("\n%d\n", hamming);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: