题
要弄明白的
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("
%d
", hamming);
}
return 0;
}