您的位置:首页 > 其它

UVa 1368:DNA Consensus String

2017-03-26 15:11 441 查看
简单的但是工作量比较大的模拟题,把程序拆分成几个部分更好。源代码如下。另外还发现一个问题,去UVA提交C代码的时候,要把中文注释删掉,不然OJ判编译错误,UvaOJ用的C90标准。

#include <stdio.h>
#include <string.h>
#define MaxLines 55
#define MaxLength 1005
#define numBases 4 // 碱基数量为4
char inSeqs[MaxLines][MaxLength]; // 用于存储n行序列
char ansSeq[MaxLength]; // 用于存储结果
int ctAGCT[numBases]; // 用于存储一列中,四种碱基出现的次数
const char bases[] = {'A', 'G', 'C', 'T'}; // 四种碱基
int T, n, m, diffs; // diffs为差异的总数

void readSeqs() // 读取输入样例
{
scanf("%d%d", &n, &m); // 读入每个测试样例的行数和每行的长度
int i;
for (i = 0; i < n; i++)
scanf("%s", inSeqs[i]);
}

void countColumn(int c) // 计算第c列中不同碱基出现的次数
{
int i;
memset(ctAGCT, 0, sizeof(ctAGCT)); // 每次统计之前需要清零
for (i = 0; i < n; i++)
{
if ('A' == inSeqs[i][c]) ctAGCT[0]++;
else if('G' == inSeqs[i][c]) ctAGCT[1]++;
else if('C' == inSeqs[i][c]) ctAGCT[2]++;
else ctAGCT[3]++;
}
}

int chooseBase(int c) // 选择第c列中出现次数最多的碱基作为该列的答案,返回出现次数最多的碱基的下标(0,1,2,3)
{
int i, index = 0; // index为出现次数最多的碱基的下标(0,1,2,3)
int biggest = ctAGCT[index]; // 初始化为碱基A的出现次数
char ansBase = 'A';
for (i = 1; i < numBases; i++) // 遍历碱基出现的次数
{
if (ctAGCT[i] > biggest) // 如果碱基bases[i]出现的次数大于碱基ansBase出现的次数,
{
biggest = ctAGCT[i]; // 更新最大出现次数
ansBase = bases[i]; // 更新碱基ansBase为该列出现次数最多的碱基
index = i;
}
else if (ctAGCT[i] == biggest) // 如果碱基bases[i]出现的次数等于碱基ansBase出现的次数,
{
if (bases[i] < ansBase) // 如果碱基bases[i]的字典序小于碱基ansBase的字典序,
{
ansBase = bases[i]; // 则选用字典序最小的作为该列的答案
index = i;
}
}
}
ansSeq[c] = ansBase; // 该列的答案
return index;
}

int countDiffs(int index) // 统计第c列的差异数,index为该列出现次数最多的碱基的下标(0,1,2,3)
{
int columnDiffs = 0, i;
for (i = 0; i < numBases; i++)
columnDiffs += ctAGCT[i];
return columnDiffs - ctAGCT[index];
}

void getAnswer() // 计算答案序列和总的差异数
{
int i, index;
diffs = 0; // 总的差异数清零
for (i = 0; i < m; i++) // 遍历每一列
{
countColumn(i); // 统计第i列中各碱基出现的次数
index = chooseBase(i); // 第i列中答案碱基的下标
diffs += countDiffs(index); // 统计第i列的差异数
}
ansSeq[m] = '\0'; // 为答案序列添加结尾
}

void printAns() // 输出答案序列和总的差异数
{
printf("%s\n", ansSeq); // 输出答案序列
printf("%d\n", diffs);// 输出总的差异数
}

int main()
{
scanf("%d", &T); // 读入测试样例数目
while (T--)
{
readSeqs(); // 读取输入
getAnswer(); // 获得答案
printAns(); // 输出答案
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: