【C/C++】习题3-7 DNA/算法竞赛入门经典/数组与字符串

【题目】
输入m组n长的DNA序列,要求找出和其他Hamming距离最小的那个序列,求其与其他的Hamming距离总和。
如果有多个序列,求字典序最小的。
【注】这道题是我理解错误,不是找出输入的序列中和其他距离最小的,而是找到一个DNA序列到所有其他的序列距离最小。
正确方法是统计每一位的AGCT出现频次,然后找到每一位出现最多的。
因为只有AGCT,所以可以用一个dict char dict = "AGCT"这样的套路存储。
【知识点】

  1. 字典序比较:strcmp
#include <string.h>
strcmp(str1, str2)

结果:
0 str1 = str2
负数 str1 < str2
正数 str1 > str2
判断是否满足str1 > str2 的条件:
if(strcmp(str1, str2))
【代码】

#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
const int max_m = 55;
const int max_n = 1005;

void show_matrix(char a[][max_n], int m, int n)
{
    for (int i = 0; i < m; i++)
    {
        printf("%s\n", a[i]);
    }
}

void show_matrix_digit(int a[][max_n], int m, int n)
{
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            printf("%d",a[i][j]);
        }
        printf("\n");
    }
}

int compare_hamming_distance(char a[][max_n], int x, int y, int n)
{
    int tot = 0;
    for (int i = 0; i < n; i++)
    {
        if (a[x][i]!=a[y][i])
        {
            tot++;
        }
    }
    return tot;
}

int count_sum_line(int a[][max_n], int m, int x) //一共m组,计算第x行
{
    int sum = 0;
    for (int i = 0; i < m; i++)
    {
        sum = sum + a[x][i];
    }
    return sum;
}

int get_min(int a[], int m) //找出数组中的最小值
{
    int min = 0x3F3F3F3F;
    for (int i = 0; i < m; i++)
    {
        if (a[i] <= min)
        {
            min = a[i];
        }
    }
    return min;
}

void get_loc(int a[], int m, int min, int b[]) //用一个全0数组b作为标记,如果某位为最小值,将这位置为1. m:数组长度
{
    for (int i = 0; i < m; i++)
    {
        if (a[i] == min)
        {
            b[i] = 1;
        }
    }
}

int main()
{
    char a[max_m][max_n]; //创建二维数组a用于存储
    int distance[max_m][max_n]; //建立距离矩阵,用于存储m组数据之间的Hamming距离
    int m, n;
    //输入二维的长,宽
    scanf("%d%d", &m, &n);
    fflush(stdin);
    //输入m组n长的序列
    for (int i = 0; i < m; i++)
    {
        scanf("%s", a[i]);
        fflush(stdin);
    }
    printf("This is your input:\n");
    show_matrix(a, m, n);
    
    //函数测试
    //int re = compare_hamming_distance(a, 0, 1, n);
    //printf("result %d\n", re);
    
    //将Hamming距离写入Hamming Distance矩阵
    for (int i = 0; i < m; i++)
    {
        for (int j = i ; j < m; j++)
        {
            distance[i][j] = compare_hamming_distance(a, i, j, n);
            distance[j][i] = compare_hamming_distance(a, i, j, n);
        }
    }
    show_matrix_digit(distance, m, m);
    
    //建立一个b数组,存储m组数据分别和其他组数据的距离
    int b[max_m];
    memset(b, 0, sizeof(b));
    for (int i = 0; i < m; i++)
    {
        b[i] = count_sum_line(distance, m, i);
    }
    int min = get_min(b, m); //找到最小值
    //找到有多少个最小值
    
    //找到对应的数组,标1
    int c[max_m];
    memset(c, 0, sizeof(c));
    get_loc(b, m, min, c);
    
    //生成字典序最大值
    char d[max_n];
    for (int i = 0; i < n; i++)
    {
        d[i] = 'Z';
    }
    
    for (int i = 0; i < m; i++)
    {
        if(c[i])
        {
            if(strcmp(d,a[i])) //字典序比较
            {
                for (int j = 0; j < n; j++)
                {
                    d[j] = a[i][j];
                }
            }
        }
    }
    
    printf("minimum hamming distance to other,the total distance is %d\n", min);
    printf("%s",d);
}
posted @ 2020-11-15 20:43  KinoLogic  阅读(148)  评论(0编辑  收藏  举报