这是题目:
5:DNA排序
查看 提交 统计 提问总时间限制: 1000ms 内存限制: 65536kB
描述
现在有一些长度相等的DNA串(只由ACGT四个字母组成),请将它们按照逆序对的数量多少排序。
逆序对指的是字符串A中的两个字符A[i]、A[j],具有i < j 且 A[i] > A[j] 的性质。如字符串”ATCG“中,T和C是一个逆序对,T和G是另一个逆序对,这个字符串的逆序对数为2。
输入
第1行:两个整数n和m,n(0<n<=50)表示字符串长度,m(0<m<=100)表示字符串数量
第2至m+1行:每行是一个长度为n的字符串
输出
按逆序对数从少到多输出字符串,逆序对数一样多的字符串按照输入的顺序输出。
样例输入
10 6
AACATGAAGG
TTTTGGCCAA
TTTGGCCAAA
GATCAGATTT
CCCGGGGGGA
ATCGATGCAT
样例输出
CCCGGGGGGA
AACATGAAGG
GATCAGATTT
ATCGATGCAT
TTTTGGCCAA
TTTGGCCAAA
==========================================================================
以归并算法为框架的求逆序对数目(时间复杂度O(nlogn))+冒泡排序。
代码清单:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define MAXLEN 55
#define MAXN 105
typedef struct _DNAinfo
{
char DNAseq[MAXLEN];
int invs;
} DNAinfo;
DNAinfo DNAdata[MAXN];
int Merge(int a[], int tempa[], int left, int right, int mid)
{
for (int i=left; i<=right; ++i)
{
tempa[i]=a[i];
}
int cursor=left;
int index1=left;
int index2=mid+1;
int delta=0;
while (index1<=mid && index2<=right)
{
if(tempa[index1]<=tempa[index2]) a[cursor++]=tempa[index1++];
else
{
a[cursor++]=tempa[index2++];
delta += (mid-index1+1);
}
}
while(index1<=mid) a[cursor++]=tempa[index1++];
while(index2<=right) a[cursor++]=tempa[index2++];
return delta;
}
void MergeCountInvs(int a[], int tempa[], int left, int right, int *cnt)
{
int mid=(left+right)/2;
if (left<right)
{
MergeCountInvs(a, tempa, left, mid, cnt);
MergeCountInvs(a, tempa, mid+1, right, cnt);
(*cnt) += Merge(a, tempa, left, right, mid);
}
}
void Swap(DNAinfo *info1, DNAinfo *info2, int n) //我晕,写了这么久代码还会在“swap函数应该传地址”上面栽跟头,不应该不应该。
{
char tempc[MAXLEN];
int tempint;
memcpy(tempc, info1->DNAseq, n);
tempint=info1->invs;
memcpy(info1->DNAseq, info2->DNAseq, n);
info1->invs=info2->invs;
memcpy(info2->DNAseq, tempc, n);
info2->invs=tempint;
}
//数据量不大,且需要稳定排序,故选择冒泡
void BubbleSortByInvs(DNAinfo DNAdata[], int m, int n)
{
bool NoSwap; //设立NoSwap标志位
for (int i=0; i<m-1; ++i) //从队首开始扫描序列
{
NoSwap=true;
for (int j=m-1; j>i; --j) //从队尾冒泡
{
if (DNAdata[j].invs < DNAdata[j-1].invs) //把小的换到前面来
{
Swap(&(DNAdata[j]), &(DNAdata[j-1]), n);
NoSwap=false;
}
}
if(NoSwap==true)
return;
}
}
int main()
{
freopen("D:\\in.txt", "r", stdin);
freopen("D:\\out.txt", "w", stdout);
int a[MAXLEN], tempa[MAXLEN];
int cnt;
int n, m;
scanf("%d%d", &n, &m);
for (int i=0; i<m; ++i)
{
scanf("%s", DNAdata[i].DNAseq);
for (int j=0; j<n; ++j)
{
a[j]=DNAdata[i].DNAseq[j];
}
cnt=0;
MergeCountInvs(a, tempa, 0, n-1, &cnt);
DNAdata[i].invs=cnt;
}
BubbleSortByInvs(DNAdata, m, n);
//输出
for (int i=0; i<m; ++i)
{
printf("%s\n", DNAdata[i].DNAseq);
}
return 0;
}