|
|
|
|
#include <iostream>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <windows.h>
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
#define INDEL_CHAR '-'
|
|
|
|
|
int MATCH = 1, DIS_MATCH = -1, INDEL = -3;
|
|
|
|
|
char choice;
|
|
|
|
|
|
|
|
|
|
class ResUnit //һ<><D2BB>˫<EFBFBD><CBAB><EFBFBD>бȶԺ<C8B6><D4BA>Ľ<EFBFBD><C4BD><EFBFBD>
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
string str1; //ԭʼ<D4AD><CABC><EFBFBD><EFBFBD>1
|
|
|
|
|
string str2; //ԭʼ<D4AD><CABC><EFBFBD><EFBFBD>2
|
|
|
|
|
string res1; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1
|
|
|
|
|
string res2; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2
|
|
|
|
|
int score; //<2F><><EFBFBD><EFBFBD><EFBFBD>ܵ÷֣<C3B7><D6A3><EFBFBD>ӳ<EFBFBD><D3B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD>Ƴ̶<C6B3>
|
|
|
|
|
int tag; //<2F><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class SingleSeq //һ<><D2BB><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD>Ϻ<EFBFBD><CFBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
string str; //һ<><D2BB><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>ԭʼ<D4AD><CABC><EFBFBD><EFBFBD>
|
|
|
|
|
string res; //һ<><D2BB><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD>Ϻ<EFBFBD><CFBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct BacktrackingUnit {
|
|
|
|
|
int goUp; //<2F>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>ϻ<EFBFBD><CFBB><EFBFBD>
|
|
|
|
|
int goLeftUp; //<2F>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϻ<EFBFBD><CFBB><EFBFBD>
|
|
|
|
|
int goLeft; //<2F>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
int score; //<2F>÷־<C3B7><D6BE><EFBFBD><EFBFBD><EFBFBD>(i, j)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>ķ<EFBFBD>ֵ
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef struct BacktrackingUnit *unitLine;
|
|
|
|
|
|
|
|
|
|
struct SequenceUnit {
|
|
|
|
|
string *str1; //ƥ<><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1
|
|
|
|
|
string *str2; //ƥ<><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2
|
|
|
|
|
int score;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
<EFBFBD>Ƚ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>֮<EFBFBD><EFBFBD>˭<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
f(i-1,j-1),f(i-1,j)+indel,f(i,j-1)+indel
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int max3(int a, int b, int c)
|
|
|
|
|
{
|
|
|
|
|
return max(max(a, b), c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
<EFBFBD>Ƚ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʲô<EFBFBD><EFBFBD>match<EFBFBD><EFBFBD>dismatch<EFBFBD><EFBFBD>indel
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int myCompare(char a, char b)
|
|
|
|
|
{
|
|
|
|
|
if (a == b)
|
|
|
|
|
return MATCH;
|
|
|
|
|
else if (a == ' ' || b == ' ')
|
|
|
|
|
return INDEL;
|
|
|
|
|
return DIS_MATCH;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ResUnit traceback(unitLine **item, const int i, const int j, string str1,
|
|
|
|
|
|
|
|
|
|
string str2, string res1, string res2, int n, ResUnit resUnit)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
unitLine temp = item[i][j];
|
|
|
|
|
if (resUnit.tag != 1) {
|
|
|
|
|
if (!(i || j)) { // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ(0, 0)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȶԵ<C8B6><D4B5><EFBFBD>
|
|
|
|
|
resUnit.str1 = str1;
|
|
|
|
|
resUnit.str2 = str2;
|
|
|
|
|
resUnit.res1 = res1;
|
|
|
|
|
resUnit.res2 = res2;
|
|
|
|
|
resUnit.tag = 1;
|
|
|
|
|
return resUnit;
|
|
|
|
|
}
|
|
|
|
|
if (temp->goUp) { // <20><><EFBFBD>ϻ<EFBFBD><CFBB><EFBFBD>һ<EFBFBD><D2BB>
|
|
|
|
|
res1 = str1[i - 1] + res1;
|
|
|
|
|
res2 = INDEL_CHAR + res2;
|
|
|
|
|
resUnit = traceback(item, i - 1, j, str1, str2, res1, res2, n + 1, resUnit);
|
|
|
|
|
}
|
|
|
|
|
if (temp->goLeftUp) { // <20><><EFBFBD><EFBFBD><EFBFBD>ϻ<EFBFBD><CFBB><EFBFBD>һ<EFBFBD><D2BB>
|
|
|
|
|
res1 = str1[i - 1] + res1;
|
|
|
|
|
res2 = str2[j - 1] + res2;
|
|
|
|
|
resUnit = traceback(item, i - 1, j - 1, str1, str2, res1, res2, n + 1, resUnit);
|
|
|
|
|
}
|
|
|
|
|
if (temp->goLeft) { // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
|
|
|
|
|
res1 = INDEL_CHAR + res1;
|
|
|
|
|
res2 = str2[j - 1] + res2;
|
|
|
|
|
resUnit = traceback(item, i, j - 1, str1, str2, res1, res2, n + 1, resUnit);
|
|
|
|
|
}
|
|
|
|
|
return resUnit;
|
|
|
|
|
}
|
|
|
|
|
return resUnit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ResUnit NeedlemanWunch(string str1, string str2)
|
|
|
|
|
{
|
|
|
|
|
//<2F>ַ<EFBFBD><D6B7><EFBFBD>str1,str2<72><32><EFBFBD><EFBFBD>
|
|
|
|
|
const int m = str1.length();
|
|
|
|
|
const int n = str2.length();
|
|
|
|
|
int m1, m2, m3, mm;
|
|
|
|
|
unitLine **unit;
|
|
|
|
|
|
|
|
|
|
// <20><>ʼ<EFBFBD><CABC>
|
|
|
|
|
if ((unit = (unitLine **)malloc(sizeof(unitLine *) * (m + 1))) == NULL) {
|
|
|
|
|
fputs("Error: Out of space!\n", stderr);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i <= m; i++) {
|
|
|
|
|
if ((unit[i] = (unitLine *)malloc(sizeof(unitLine) * (n + 1))) == NULL) {
|
|
|
|
|
fputs("Error: Out of space!\n", stderr);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
for (int j = 0; j <= n; j++) {
|
|
|
|
|
if ((unit[i][j] = (unitLine)malloc(sizeof(struct BacktrackingUnit))) == NULL) {
|
|
|
|
|
fputs("Error: Out of space!\n", stderr);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
unit[i][j]->goUp = 0;
|
|
|
|
|
unit[i][j]->goLeftUp = 0;
|
|
|
|
|
unit[i][j]->goLeft = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
unit[0][0]->score = 0;
|
|
|
|
|
|
|
|
|
|
for (int i = 1; i <= m; i++) {
|
|
|
|
|
unit[i][0]->score = INDEL * i;
|
|
|
|
|
unit[i][0]->goUp = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int j = 1; j <= n; j++) {
|
|
|
|
|
unit[0][j]->score = INDEL * j;
|
|
|
|
|
unit[0][j]->goLeft = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><>̬<EFBFBD>滮<EFBFBD>㷨<EFBFBD><E3B7A8><EFBFBD><EFBFBD><EFBFBD>÷־<C3B7><D6BE><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD>Ԫ<EFBFBD>ķ<EFBFBD>ֵ
|
|
|
|
|
for (int i = 1; i <= m; i++) {
|
|
|
|
|
for (int j = 1; j <= n; j++) {
|
|
|
|
|
m1 = unit[i - 1][j]->score + INDEL;
|
|
|
|
|
m2 = unit[i - 1][j - 1]->score + myCompare(str1[i - 1], str2[j - 1]);
|
|
|
|
|
m3 = unit[i][j - 1]->score + INDEL;
|
|
|
|
|
mm = max3(m1, m2, m3);
|
|
|
|
|
unit[i][j]->score = mm;
|
|
|
|
|
//<2F>ж<EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD>Դ
|
|
|
|
|
if (m1 == mm)
|
|
|
|
|
unit[i][j]->goUp = 1;
|
|
|
|
|
if (m2 == mm)
|
|
|
|
|
unit[i][j]->goLeftUp = 1;
|
|
|
|
|
if (m3 == mm)
|
|
|
|
|
unit[i][j]->goLeft = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
|
|
|
|
|
ResUnit res;
|
|
|
|
|
res.tag = 0;
|
|
|
|
|
res = traceback(unit, m, n, str1, str2, "", "", 0, res);
|
|
|
|
|
res.score = unit[m][n]->score;
|
|
|
|
|
|
|
|
|
|
//<2F>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
|
|
|
|
|
for (int i = 0; i <= m; i++) {
|
|
|
|
|
for (int j = 0; j <= n; j++) {
|
|
|
|
|
free(unit[i][j]);
|
|
|
|
|
}
|
|
|
|
|
free(unit[i]);
|
|
|
|
|
}
|
|
|
|
|
free(unit);
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>ֵ
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool legal_string(string s)
|
|
|
|
|
{
|
|
|
|
|
for (unsigned i = 0; i < s.size(); i++) {
|
|
|
|
|
if (s[i] != 'A' && s[i] != 'T' && s[i] != 'C' && s[i] != 'G')
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void read(string &a, string &b)
|
|
|
|
|
{
|
|
|
|
|
char c;
|
|
|
|
|
if (!choice) {
|
|
|
|
|
while (true) {
|
|
|
|
|
cout << "<EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n1.<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>\n2.<2E><><EFBFBD><EFBFBD>Ϊ<EFBFBD>ı<EFBFBD>\n";
|
|
|
|
|
cin >> choice;
|
|
|
|
|
if (choice != '1' && choice != '2') {
|
|
|
|
|
cout << "#<23><>ѡ<EFBFBD><D1A1><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD>ѡ<EFBFBD>\n";
|
|
|
|
|
Sleep(1000);
|
|
|
|
|
} else
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>ȶԵĻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>\n<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ:";
|
|
|
|
|
cin >> a;
|
|
|
|
|
if (legal_string(a))
|
|
|
|
|
break;
|
|
|
|
|
else {
|
|
|
|
|
cout << "#<23><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>\n";
|
|
|
|
|
Sleep(1000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
cout << "<EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>:";
|
|
|
|
|
cin >> b;
|
|
|
|
|
if (legal_string(b))
|
|
|
|
|
break;
|
|
|
|
|
else {
|
|
|
|
|
cout << "#<23><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>\n";
|
|
|
|
|
Sleep(1000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
cout << "<EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD><EFBFBD>ȶԹ<EFBFBD><EFBFBD><EFBFBD>:\n1.<2E><>ȱ<EFBFBD><C8B1><EFBFBD>ȣ<EFBFBD>Ĭ<EFBFBD>ϣ<EFBFBD>\n2.<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n3.û<><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n";
|
|
|
|
|
cin >> c;
|
|
|
|
|
if (c != '1' && c != '2' && c != '3') {
|
|
|
|
|
cout << "#<23><>ѡ<EFBFBD><D1A1><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD>ѡ<EFBFBD>\n";
|
|
|
|
|
Sleep(1000);
|
|
|
|
|
} else
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (c == '2') {
|
|
|
|
|
DIS_MATCH = -3;
|
|
|
|
|
INDEL = -1;
|
|
|
|
|
|
|
|
|
|
} else if (c == '3') {
|
|
|
|
|
DIS_MATCH = INDEL = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main()
|
|
|
|
|
{
|
|
|
|
|
while (true) {
|
|
|
|
|
string a, b;
|
|
|
|
|
read(a, b);
|
|
|
|
|
ResUnit s = NeedlemanWunch(a, b);
|
|
|
|
|
if (choice == '2') {
|
|
|
|
|
ofstream ofile{"ANS.txt", ios::out};
|
|
|
|
|
ofile << s.res1 << endl;
|
|
|
|
|
ofile << s.res2 << endl;
|
|
|
|
|
ofile.close();
|
|
|
|
|
} else {
|
|
|
|
|
cout << s.res1 << endl;
|
|
|
|
|
cout << s.res2 << endl;
|
|
|
|
|
}
|
|
|
|
|
Sleep(2000);
|
|
|
|
|
cout << "<EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n1.<2E><><EFBFBD><EFBFBD><EFBFBD>ȶ<EFBFBD>\n2.ֹͣ<CDA3>ȶ<EFBFBD>\n";
|
|
|
|
|
char c;
|
|
|
|
|
while (true) {
|
|
|
|
|
cin >> c;
|
|
|
|
|
if (c != '1' && c != '2') {
|
|
|
|
|
cout << "#<23><>ѡ<EFBFBD><D1A1><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD>ѡ<EFBFBD>\n";
|
|
|
|
|
Sleep(1000);
|
|
|
|
|
} else
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (c == '2')
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
"GGATCGA"
|
|
|
|
|
"GAATTCAGTTA"
|
|
|
|
|
*/
|