POJ 1007 DNA 排序

Time Limit: 1000MS Memory Limit: 10000K

描述

对于一个序列中,”无序度”的度量,可以是次序颠倒的条目对的数量。例如,在字母序列”DAABEC”中,无序数为5,因为D比他右边的四个字母都大,E比它右侧的1个字母打。这种度量方法成为序列颠倒数。序列”AACEDGG”的逆序数是1(只有E和D),该序列几乎是有序的,然而序列”ZWQM”有6个颠倒(这种情况是最无序的,即完全逆序)

你将负责排列一个DNA strings序列(序列仅包含四种字母,A、C、G、T)。然而,你想要排列,且不是按字母顺序,而是按照“有序度”的顺序,从”最有序”排列到“最无序”。所有的strings具有相同长度。

输入

第一行包含两个整数:一个正整数 n(0<n50) 给出了strings的长度;一个正整数 m(0<m100) 该处了strings的数量。之后是 m 行strings,每行string长度为n

输出

输出是输入strings的列表,从”最有序”排列到”最无序”。两个strings的无序度可能相同,此时按照原来的顺序输出即可。

输入样例

10 6
AACATGAAGG
TTTTGGCCAA
TTTGGCCAAA
GATCAGATTT
CCCGGGGGGA
ATCGATGCAT

输出样例

CCCGGGGGGA
AACATGAAGG
GATCAGATTT
ATCGATGCAT
TTTTGGCCAA
TTTGGCCAAA

思路

1、逆序数可从后往前扫描,每次记录ACG出现的次数,当前字母比前一刻扫描的字母大时,逆序数加上之前小字母出现的总次数

<—————————
序列   T T G G C C A A
逆序数  6 6 4 4 2 2 0 0

2、字符串最长50,所以char型数组要申请51,因为字符串末尾的’\n’

C++实现

#include <iostream>
#include <algorithm>

typedef struct DNA
{
    int count;// 逆序数的个数
    char DNAStr[110];
} DNA;

int N;
int SIZE;
int countA,countC,countG;


/** 计算DNA字符串的逆序数  */
int getDNAInversionNumber(char* dnaStr)
{
    int count = 0;
    countA = countC = countG = 0;
    for(int j = SIZE-1; j >= 0; j--)
    {
        switch(dnaStr[j])
        {
        case 'A':
            countA++;
            break;
        case 'C':
            countC++;
            count += countA;
            break;
        case 'G':
            countG++;
            count += countA;
            count += countC;
            break;
        case 'T':
            count += countA;
            count += countC;
            count += countG;
            break;
        }
    }
    return count;
}

int cmp(const void* a, const void* b)
{
    DNA* DNA_A = (DNA*)a;
    DNA* DNA_B = (DNA*)b;
    return (DNA_A->count) - (DNA_B->count);
}

int main()
{
    using namespace std;
    while(cin >> SIZE >> N)
    {
        DNA* dnas = new DNA[N];
        for(int i = 0; i < N; i++)
        {
            cin >> dnas[i].DNAStr;
            dnas[i].count = getDNAInversionNumber(dnas[i].DNAStr);
        }

        qsort(dnas, N, sizeof(DNA), cmp);

        for(int i = 0; i < N; i++)
        {
            cout << dnas[i].DNAStr << endl;
        }
    }
    return 0;
}

参考

http://www.cnblogs.com/csulennon/p/4167981.html

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值