1. 程式人生 > 實用技巧 >【C/C++】習題3-7 DNA/演算法競賽入門經典/陣列與字串

【C/C++】習題3-7 DNA/演算法競賽入門經典/陣列與字串

【題目】
輸入m組n長的DNA序列,要求找出和其他Hamming距離最小的那個序列,求其與其他的Hamming距離總和。
如果有多個序列,求字典序最小的。
【知識點】

  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);
}