第一版(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")
- 怀疑是这里设置的temp的初始化不对,第二版以后对这里做了修改。
- 但是后来用第五版重测,发现temp初始化为0,也可以AC,这说明这里的修改是影响不大的。
- 为什么会出现这种情况呢?temp实质上是在记录待输出字符串的下标,初始化为0说明,当temp不更新时,默认输出从左到右第一个长度为l的子串。
- 我们考虑一下,什么时候会采取默认输出?当i从后走到前,都没有找到比例等于或大于0的数的时候,而这是显然不可能的。
- 为什么不可能?在你的子串长度小于或等于DNA序列的情况下,你从后往前遍历,哪怕一个CG都没有,也等于0,也要更换自己的temp。
- 当然,如果能提前考虑到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")
- 报错:请检查是否存在数组、列表等越界非法访问,内存非法访问等情况
- 检查后认为应该是
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")
- 分析一下发现错在「误认为
all_ratio
和s
的大小相同」。
第四版(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")
- 报错:请检查是否存在数组、列表等越界非法访问,内存非法访问等情况。
第五版(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")
- 请检查是否存在数组、列表等越界非法访问,内存非法访问等情况。
- 仔细检查后发现问题出在
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")
- 实在想不到问题,问AI没想到真正的问题是
max_ratio
应该是浮点数。 - 你用浮点数和整数比较,以及把浮点数赋值给整数,都是有问题的,你这个精度一丢失,后面的都不准了。
第八版(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")
- 改掉了精度问题,同时优化了一下代码,让
gcRatio(temp)
计算子串比例这一步只算一次而不是两次。