DNA序列(DNA Consensus Strings)

该博客探讨如何找到一个DNA序列,使其与给定的多个DNA序列的汉明距离总和最小。通过按列比较并结合字典序,提出了解决问题的算法,并提供了通过评测的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

输入m个长度均为n的DNF序列,求一个DNF序列,到所有的序列总Hamming距离尽量小。两个等长字符串的Hamming距离等于字符不同的位置个数,例如,ACGT和GCGA的Hamming距离为2,。

input

3
5 8
TATGATAC
TAAGCTAC
AAAGATCC
TGAGATAC
TAAGATGT
4 10
ACGTACGTAC
CCGTACGTAG
GCGTACGTAT
TCGTACGTAA
6 10
ATGTTACCAT
AAGTTACGAT
AACAAAGCAA
AAGTTACCTT
AAGTTACCAA
TACTTACCAA

output

TAAGATAC
7
ACGTACGTAA
6
AAGTTACCAA
12


思路分析:注意到题目要求是找出一个DNA序列,即重组一个DNF序列= =。我的想法就是按列搜索,先比较距离,如果距离相同再比较字典序。然后组合即可。附上代码,已经经过UVAOJ评测。

#include <iostream>
#include <string>
#include <string.h>
#include <ostream>
#include <fstream>
#include<cstdio>
#include<vector>
#define INFTY 2147483647

/*
5
5 8
TATGATAC
TAAGCTAC
AAAGATCC
TGAGATAC
TAAGATGT
4 10
ACGTACGTAC
CCGTACGTAG
GCGTACGTAT
TCGTACGTAA
6 10
ATGTTACCAT
AAGTTACGAT
AACAAAGCAA
AAGTTACCTT
AAGTTACCAA
TACTTACCAA
3 4
GATA
AGAT
CGTA
5 7
ATGTTAC
TTACCTT
TTACCAA
GTACGTA
AAGATCC
*/
using namespace std;

int m, n, T;
string s[50];
vector<char>minstr;
int label;

void search(int k)
{


    int i, j, temp = 0, temp1 = INFTY; //temp记录当前字母的Hamming距离和,temp1记录截止到当前字母的所有搜索最小的距离
    char tempc;//记录记录截止到当前字母的所有搜索最小距离的字母
    //cout << "the present tagat is " <<endl<<endl;


    for(i = 0; i < m; i++)
    {
        for(j = 0; j < m; j++)
        {
            if(s[i][k] != s[j][k])temp++;
        }
        //cout << "temp is " << temp <<endl;

        if(temp1 > temp)
        {
            temp1 = temp;
            tempc = s[i][k];
        }
        if(temp1 == temp)
        {
            if(s[i][k] < tempc)tempc = s[i][k];
        }
        //cout <<"tempc is " << tempc << endl;
       // cout <<"temp1 is " << temp << endl;
        temp = 0;

    }
    minstr.push_back(tempc);
   // for(char p : minstr)
   //     cout << p;
   // cout <<endl;
    label = label + temp1;
}

int main()
{
  //  ofstream savefile("D:\\test.txt");
    cin >> T;
    while(T--)
    {
        cin >> m >> n;
        //cout << "n is" << n <<endl;
        getchar();
        for(int i = 0; i < m; i++)
            getline(cin, s[i]);
         //cout << s[0] << endl;
       //  for(int i = 0; i < m; i++)
        //    cout << s[i] << endl;
       //  cout <<label <<endl;
        for(int i = 0; i < n; i++)
        {
            search(i);
        }


        for(char p : minstr)
            cout << p/*, savefile << p */;
        cout <<endl;
       // savefile << endl;

        cout << label << endl;
     //   savefile << label << endl;
        label = 0;

        minstr.clear();
        //minstr.clear();
    }
   // savefile.close();
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值