你的任务是分类DNA字符串(只有ACGT四个字符)。但是你分类它们的方法不是字典序,而是逆序数,排序程度从好到差。所有字符串长度相同。
输入:1、纯粹使用数组来实现比较麻烦,当然也是可以实现的,我的第一个程序就是用数组实现的,选取的数据结构为:
typedef struct { int DNAnum; char str[52]; }NodeDNA;2、计算每个字符串的逆序数,根据题意来计算即可;
int DNAcount(char* destination, int len) { /* 统计每个字符串的DNA值 */ int iterX = 0; int iterY = 0; int cnt = 0; for(iterX = 0; iterX < len - 1; iterX++) { if(destination[iterX] == 'A') { continue; } for(iterY = iterX + 1; iterY < len; iterY++) { if(destination[iterX] > destination[iterY]) { cnt++; } } } return cnt; }字符串里面假设有字母 'A' ,是可以直接跳过的,因为字母 'A' 不影响逆序数,所以,程序才加入了if语言来判断;
#include <stdio.h> #include <stdlib.h> typedef struct { int DNAnum; char str[52]; }NodeDNA; int DNAcount(char* destination, int len) { /* 统计每个字符串的DNA值 */ int iterX = 0; int iterY = 0; int cnt = 0; for(iterX = 0; iterX < len - 1; iterX++) { if(destination[iterX] == 'A') { continue; } for(iterY = iterX + 1; iterY < len; iterY++) { if(destination[iterX] > destination[iterY]) { cnt++; } } } return cnt; } int cmp(const void* a,const void* b) { NodeDNA* x=(NodeDNA*)a; NodeDNA* y=(NodeDNA*)b; return (x -> DNAnum) - (y -> DNAnum); } int main(void) { NodeDNA NoDNA[101]; int col = 0; int row = 0; int iter = 0; //scanf("%d%d", &col, &row); //fflush(stdin); while( scanf("%d%d", &col, &row) != EOF ) { getchar(); for(iter = 0; iter < row; iter++) { gets(NoDNA[iter].str); NoDNA[iter].DNAnum = DNAcount(NoDNA[iter].str, col); } qsort(NoDNA, row, sizeof(NodeDNA),cmp); for(iter = 0; iter < row; iter++) { puts(NoDNA[iter].str); } } return 0; }另外,需要说明的一点是,计算逆序数的还有一个复杂度为O(n)的算法;
int InversionNumber(char* s,int len) { int ans=0; //s逆序数 int A, C, G , i; //各个字母出现次数 A = C = G = 0; for( i = len-1;i >= 0;i--) { switch(s[i]) { case 'A':A++;break; //A是最小的,无逆序数 case 'C': { C++; ans+=A; //当前C后面出现A的次数就是这个C的逆序数 break; } case 'G': { G++; ans+=A; ans+=C; break; } case 'T': { ans+=A; ans+=C; ans+=G; break; } } } return ans; }