第一版(2/10)

#include <iostream>
#include <string>
#include <vector>
using namespace std;

// 写一个函数计算字符串中的GC比例

double gcRatio(const string &s){
    double count = 0;
    for (char c : s) {
        if(c == 'C' || c == 'G'){
            count++;
        }
    }

    double gc_ratio = count / s.size(); 
    return gc_ratio;
}

int main() {
    string s;
    int l;
    cin >> s >> l;

    // 我们先从左往右统计一遍可输出子串的GC比例
    // 然后我们把这个比例放到一个数组里
    // 数组的脚标就是子串的起始位置
    // 我们找到数组中的最大值,并从左到右找到第一个子串

    vector<double> all_ratio; 
    for(int i = 0; i < s.size(); i++){
        all_ratio[i] = gcRatio(s.substr(i, l));
    }

    double max = 0;
    int temp = 0;
    for(int i = all_ratio.size() - 1; i >= 0; i--){
        if(all_ratio[i] >= max) {
            max = all_ratio[i];    
            temp = i;
        }
    }

    cout << s.substr(temp, l) << endl;

}
// 64 位输出请用 printf("%lld")

  1. 怀疑是这里设置的temp的初始化不对,第二版以后对这里做了修改。
  2. 但是后来用第五版重测,发现temp初始化为0,也可以AC,这说明这里的修改是影响不大的。
  3. 为什么会出现这种情况呢?temp实质上是在记录待输出字符串的下标,初始化为0说明,当temp不更新时,默认输出从左到右第一个长度为l的子串。
  4. 我们考虑一下,什么时候会采取默认输出?当i从后走到前,都没有找到比例等于或大于0的数的时候,而这是显然不可能的。
  5. 为什么不可能?在你的子串长度小于或等于DNA序列的情况下,你从后往前遍历,哪怕一个CG都没有,也等于0,也要更换自己的temp。
  6. 当然,如果能提前考虑到temp的问题,将temp初始化为all_ratio.size() - 1,这个是更严谨的选择。

第二版(0/10,非法访问)

#include <iostream>
#include <string>
#include <vector>
using namespace std;

// 写一个函数计算字符串中的GC比例

double gcRatio(const string &s){
    double count = 0;
    for (char c : s) {
        if(c == 'C' || c == 'G'){
            count++;
        }
    }

    double gc_ratio = count / s.size(); 
    return gc_ratio;
}

int main() {
    string s;
    int l;
    cin >> s >> l;

    // 我们先从左往右统计一遍可输出子串的GC比例
    // 然后我们把这个比例放到一个数组里
    // 数组的脚标就是子串的起始位置
    // 我们找到数组中的最大值,并从左到右找到第一个子串

    vector<double> all_ratio; 
    for(int i = 0; i < s.size(); i++){
        all_ratio[i] = gcRatio(s.substr(i, l));
    }

    double max = 0;
    int temp = all_ratio.size() - 1;
    for(int i = all_ratio.size() - 1; i >= 0; i--){
        if(all_ratio[i] >= max) {
            max = all_ratio[i];    
            temp = i;
        }
    }

    cout << s.substr(temp, l) << endl;

}
// 64 位输出请用 printf("%lld")

  1. 报错:请检查是否存在数组、列表等越界非法访问,内存非法访问等情况
  2. 检查后认为应该是all_ratio一开始的初始化没做好,没有规定它的大小。

第三版(2/10)

#include <iostream>
#include <string>
#include <vector>
using namespace std;

// 写一个函数计算字符串中的GC比例

double gcRatio(const string &s){
    double count = 0;
    for (char c : s) {
        if(c == 'C' || c == 'G'){
            count++;
        }
    }

    double gc_ratio = count / s.size(); 
    return gc_ratio;
}

int main() {
    string s;
    int l;
    cin >> s >> l;

    // 我们先从左往右统计一遍可输出子串的GC比例
    // 然后我们把这个比例放到一个数组里
    // 数组的脚标就是子串的起始位置
    // 我们找到数组中的最大值,并从左到右找到第一个子串

    vector<double> all_ratio(s.size(), 0); 
    for(int i = 0; i < s.size(); i++){
        all_ratio[i] = gcRatio(s.substr(i, l));
    }

    double max = 0;
    int temp = all_ratio.size() - 1;
    for(int i = all_ratio.size() - 1; i >= 0; i--){
        if(all_ratio[i] >= max) {
            max = all_ratio[i];    
            temp = i;
        }
    }

    cout << s.substr(temp, l) << endl;

}
// 64 位输出请用 printf("%lld")

  1. 分析一下发现错在「误认为all_ratios的大小相同」。

第四版(9/10,非法访问)

#include <iostream>
#include <string>
#include <vector>
using namespace std;

// 写一个函数计算字符串中的GC比例

double gcRatio(const string &s){
    double count = 0;
    for (char c : s) {
        if(c == 'C' || c == 'G'){
            count++;
        }
    }

    double gc_ratio = count / s.size(); 
    return gc_ratio;
}

int main() {
    string s;
    int l;
    cin >> s >> l;

    // 我们先从左往右统计一遍可输出子串的GC比例
    // 然后我们把这个比例放到一个数组里
    // 数组的脚标就是子串的起始位置
    // 我们找到数组中的最大值,并从左到右找到第一个子串

    vector<double> all_ratio(s.size() - l, 0); 
    for(int i = 0; i < s.size() - l; i++){
        all_ratio[i] = gcRatio(s.substr(i, l));
    }

    double max = 0;
    int temp = all_ratio.size() - 1;
    for(int i = all_ratio.size() - 1; i >= 0; i--){
        if(all_ratio[i] >= max) {
            max = all_ratio[i];    
            temp = i;
        }
    }

    cout << s.substr(temp, l) << endl;

}
// 64 位输出请用 printf("%lld")

  1. 报错:请检查是否存在数组、列表等越界非法访问,内存非法访问等情况。

第五版(AC)

#include <iostream>
#include <string>
#include <vector>
using namespace std;

// 写一个函数计算字符串中的GC比例

double gcRatio(const string &s){
    double count = 0;
    for (char c : s) {
        if(c == 'C' || c == 'G'){
            count++;
        }
    }

    double gc_ratio = count / s.size(); 
    return gc_ratio;
}

int main() {
    string s;
    int l;
    cin >> s >> l;

    // 我们先从左往右统计一遍可输出子串的GC比例
    // 然后我们把这个比例放到一个数组里
    // 数组的脚标就是子串的起始位置
    // 我们找到数组中的最大值,并从左到右找到第一个子串

    vector<double> all_ratio(s.size() - l + 1, 0); 
    for(int i = 0; i <= s.size() - l; i++){
        all_ratio[i] = gcRatio(s.substr(i, l));
    }

    double max = 0;
    int temp = all_ratio.size() - 1;
    for(int i = all_ratio.size() - 1; i >= 0; i--){
        if(all_ratio[i] >= max) {
            max = all_ratio[i];    
            temp = i;
        }
    }

    cout << s.substr(temp, l) << endl;

}
// 64 位输出请用 printf("%lld")

第六版(更加简洁,但0/10+非法访问)

#include <iostream>
#include <string>
#include <vector>
using namespace std;

double gcRatio(const string &s){
    double count = 0;
    for (char c : s) {
        if(c == 'C' || c == 'G'){
            count++;
        }
    }

    return count / s.size(); 
}

int main() {
    string s;
    int l;
    cin >> s >> l;

    string max_str;
    int max_ratio = 0;
    for (int i = s.size() - l; i >= 0; i++) {
        if(gcRatio(s.substr(i, l)) > max_ratio){
            max_ratio = gcRatio(s.substr(i, l));
            max_str = s.substr(i, l);
        }
    }

    cout << max_str << endl;

}
// 64 位输出请用 printf("%lld")

  1. 请检查是否存在数组、列表等越界非法访问,内存非法访问等情况。
  2. 仔细检查后发现问题出在i++,设置的i是从大变小的,用i--才对。

第七版(2/10)

#include <iostream>
#include <string>
#include <vector>
using namespace std;

double gcRatio(const string &s){
    double count = 0;
    for (char c : s) {
        if(c == 'C' || c == 'G'){
            count++;
        }
    }

    return count / s.size(); 
}

int main() {
    string s;
    int l;
    cin >> s >> l;

    string max_str = "";
    int max_ratio = 0;
    for (int i = s.size() - l; i >= 0; i--) {
        string temp = s.substr(i, l);
        if(gcRatio(temp) >= max_ratio){
            max_ratio = gcRatio(temp);
            max_str = temp;
        }
    }

    cout << max_str << endl;

}
// 64 位输出请用 printf("%lld")

  1. 实在想不到问题,问AI没想到真正的问题是max_ratio应该是浮点数。
  2. 你用浮点数和整数比较,以及把浮点数赋值给整数,都是有问题的,你这个精度一丢失,后面的都不准了。

第八版(AC)

#include <iostream>
#include <string>
#include <vector>
using namespace std;

double gcRatio(const string &s){
    double count = 0;
    for (char c : s) {
        if(c == 'C' || c == 'G'){
            count++;
        }
    }

    return count / s.size(); 
}

int main() {
    string s;
    int l;
    cin >> s >> l;

    string max_str = "";
    double max_ratio = 0;
    for (int i = s.size() - l; i >= 0; i--) {
        string temp = s.substr(i, l);
        double temp_ratio = gcRatio(temp);
        if(temp_ratio >= max_ratio){
            max_ratio = temp_ratio;
            max_str = temp;
        }
    }

    cout << max_str << endl;

}
// 64 位输出请用 printf("%lld")

  1. 改掉了精度问题,同时优化了一下代码,让gcRatio(temp)计算子串比例这一步只算一次而不是两次。