青训营-环状DNA序列整理

243 阅读2分钟

环状DNA序列整理

环状 DNA 又称超螺旋,即一段碱基序列呈现环状,在分析时,需要将相同序列的环状 DNA 分到相同组内,现需将环状碱基序列按照最小表示法进行排序。

一段长度为 n 的碱基序列,按照顺时针方向,碱基序列可以从任意位置起开始该序列顺序,因此长度为 n 的碱基序列有 n 种表示法。例如:长度为 6 的碱基序列 CGAGTC,有 CGAGTCGAGTCCAGTCCG 等表示法。在这些表示法中,字典序最小的称为“最小表示”。

输入一个长度为 nn <= 100)的环状碱基序列(只包含 ACGT 这 4 种碱基)的一种表示法,输出该环状碱基序列的最小表示。

例如: ATCA 的最小表示是 AATC CGAGTC 的最小表示是 AGTCCG

输入描述

一段 DNA 碱基序列

输出描述

DNA 碱基序列的最小表示

备注n <= 100 DNA 由大写英文字母 AGCT 组成

示例 1 输入:ATCA 输出:AATC

示例 2 输入:CGAGTC 输出:AGTCCG

解题思路

为了解决这个问题,我们需要将环状DNA的每种碱基排序表示出来并进行比较,得到最小表示

1.以不同起点表示字符串

为实现这一步,我们需要利用substr()函数
形式 : s.substr(pos, len) —— pos是必须的参数
返回值: string,包含s中从pos开始的len个字符的拷贝(pos的默认值是0len的默认值是s.size() - pos,即不加参数会默认拷贝整个s
异常 :若pos的值超过了string的大小,则substr函数会抛出一个out_of_range异常;若pos+n的值超过了string的大小,则substr会调整n的值,只拷贝到string的末尾

  • current用于存储当前比较 current = dna_sequence.substr(i) + dna_sequence.substr(0, i);

2.当前字符串与最小字符串进行比较,更新最小表示的起始位置

  • 初始化最小表示的起始位置为 0 int result = 0; -比较(注意:字符串字典序大小可以直接比较字符串大小得出)
    if (current < dna_sequence.substr(result, n - result) + dna_sequence.substr(0, result)) {result = i; }

3.构建最小表示

std::string r = dna_sequence.substr(result) + dna_sequence.substr(0, result);

算法实现

#include <iostream>
#include <string>

std::string solution(std::string dna_sequence) {
    // 首先确定序列的长度
    int n = dna_sequence.length();
    // 初始化最小表示的起始位置为 0
    int result = 0;
    // 用于存储当前比较的表示
    std::string current;
    for (int i = 0; i < n; i++) {
        current = dna_sequence.substr(i) + dna_sequence.substr(0, i);
        // 如果当前表示字典序小于之前的最小表示
        if (current < dna_sequence.substr(result, n - result) + dna_sequence.substr(0, result)) {
            result = i;
        }
    }
    // 构建最小表示
    std::string r = dna_sequence.substr(result) + dna_sequence.substr(0, result);
    return r;
}

int main() {
    // You can add more test cases here
    std::cout << (solution("ATCA") == "AATC") << std::endl;
    std::cout << (solution("CGAGTC") == "AGTCCG") << std::endl;
    std::cout << (solution("TCATGGAGTGCTCCTGGAGGCTGAGTCCATCTCCAGTAG") == "AGGCTGAGTCCATCTCCAGTAGTCATGGAGTGCTCCTGG") << std::endl;
    return 0;
}