C++-PTA 求解按“最多排序”到“最小排序”的顺序排列问题。

一、题目

在这里插入图片描述
在这里插入图片描述

二、算法思路

这道题目光从题目看起来很复杂,实际上我们可以使用函数将一个问题分解成两个问题来解决。
题目要求的是先对每一行的字符串求解对应的度量值,然后将字符串按度量值从小到大的顺序进行排序

第一个问题就是如何求解度量值,比较容易发现规律的是DAABEC度量值为5这个例子。
计算度量值的方法如下:

  1. 字母D:从D之后有四个字母AABC都小于D,所以这个字母的度量值为4
  2. 字母A:因为A是26个字母中最小的,所以从字母A之后的字符没有更小的了,其度量值为0
  3. 字母A度量值为0
  4. 字母B:字母B仅大于A,而从该字母之后没有A了,所以度量值为0
  5. 字母E:E大于C,所以度量值为1
  6. 字母C:由于C位于末尾,右侧没有更小的了,度量值为0
    最后就是将步骤1-6每个字母的度量值进行相加,所以DAABEC的度量值就为5了

然后就是设计一个结构体,存储DNA序列和对应的度量值。
如果你不清楚结构体的知识,可以到C 结构体 | 菜鸟教程中查看,定义结构体的方法不止下面一种。

struct letter
{
    string dna;//DNA序列
    int len=0;//度量值
};

因为DNA序列不止一个,所以在定义的时候就需要定义成结构体数组。

letter xulie[102];//结构体数组

先创建一个函数,用于计算一个字符串的度量值并返回度量值。
字母a-z对应的ASCII码是65-90,而字母A-Z对应的ASCII码是97-122
我们对字符进行int类型转换就可以直接转换成对应的ascii码了。

int check_len(string dna,int n)//计算字符串对应的度量值
{
    int len = 0;
    int i,j;
    for(i=0;i<n;i++)//遍历整个字符串
    {
        for(j=i;j<n;j++)//遍历从i之后的字符串
        {
            if((int)dna[i]>(int)dna[j])//若ascii越大,即字母较大时
            {
                len++;
            }
        }
    }
    return len;
}

对每一个dna序列计算度量值

for(i=1;i<=m;i++)//计算度量值
        xulie[i].len = check_len(xulie[i].dna,n);

判断完所有dna序列的度量值后,就可以进行冒泡递增排序。
排序完毕后就可以按顺序输出所有的dna序列了。

for(i=1;i<=m;i++)//根据度量值进行递增排序
    {
        for(j=1;j<m;j++)//字符串数组尾部不需要排序
        {
            if(xulie[j].len>xulie[j+1].len)//当前的度量值大于后者时
            {
                //dna序列替换
                string tmp_dna = xulie[j].dna;
                xulie[j].dna = xulie[j+1].dna;
                xulie[j+1].dna = tmp_dna;
                //度量值替换
                int tmp = xulie[j].len;
                xulie[j].len = xulie[j+1].len;
                xulie[j+1].len = tmp;
            }
        }
    }

三、代码

在这里插入图片描述

//作者:小狐狸
#include<iostream>
using namespace std;
struct letter
{
    string dna;//DNA序列
    int len=0;//度量值
};
int check_len(string dna,int n)//计算字符串对应的度量值
{
    int len = 0;
    int i,j;
    for(i=0;i<n;i++)//遍历整个字符串
    {
        for(j=i;j<n;j++)//遍历从i之后的字符串
        {
            if((int)dna[i]>(int)dna[j])//若ascii越大,即字母较大时
            {
                len++;
            }
        }
    }
    return len;
}
int main()
{
    int n;//字符串长度
    int m;//字符串个数
    int i,j;
    cin>>n>>m;
    letter xulie[102];//结构体数组
    for(i=1;i<=m;i++)//输入
        cin>>xulie[i].dna;
    for(i=1;i<=m;i++)//计算度量值
        xulie[i].len = check_len(xulie[i].dna,n);
    for(i=1;i<=m;i++)//根据度量值进行递增排序
    {
        for(j=1;j<m;j++)//字符串数组尾部不需要排序
        {
            if(xulie[j].len>xulie[j+1].len)//当前的度量值大于后者时
            {
                //dna序列替换
                string tmp_dna = xulie[j].dna;
                xulie[j].dna = xulie[j+1].dna;
                xulie[j+1].dna = tmp_dna;
                //度量值替换
                int tmp = xulie[j].len;
                xulie[j].len = xulie[j+1].len;
                xulie[j+1].len = tmp;
            }
        }
    }
    for(i=1;i<=m;i++)//输出
        cout<<xulie[i].dna<<endl;
    return 0;
}

  • 23
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦之海岛

创作不易,狐狸叹气

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值