注册 登录
编程论坛 C++教室

请问这个程序该怎么改

xyhuuz 发布于 2023-10-11 14:43, 2151 次点击
求大佬给看一下

程序代码:

/*
给定长度为 n 且只含有 A、T、C、G和?的字符串s,其中?可以转换为任何一个字母。
问是否存在一个字符串,使得将所有的?替换成字母后,A、T、C、G个数相等。

输入两行
第一行,一个整数n(4<=n<=255),表示字符串的长度
第二行,一个字符串s

输出一行
表示将所有的?替换成字母后使得A、T、C、G个数相等的字符串,
若不存在输出“===”(不含引号)。

Examples

input1
8
AG?C??CT

output1
AGACGTCT

input2
6
????G?

output2
===

input3
4
AA??

 
output3
===

*/
#include<iostream>
using namespace std;
int main(){
    char x[256];
    int a[4]={0};
    char g[4]={'A','C','G','T'};
    int i,k,c,d=0,flag=0,e=0;
    scanf("%d",&k);
    if((k%4)!=0){//长度不是4的倍数直接===
        printf("===");
        return 0;
    }
    x[k]='\0';
    for(i=0;i<k;i++){
        scanf(" %c",&x[i]);
        if(x[i]=='?') e++;//统计?出现次数
        switch(x[i]){//统计各字母出现次数
            case 'A':a[0]++; break;
            case 'C':a[1]++; break;
            case 'G':a[2]++; break;
            case 'T':a[3]++; break;
        }
    }
    if(e==0) goto print;//如果没有?直接输出原字符串
    c=k/4;//每个字母应该有的数量
    for(i=0;i<4;i++){
        if(a[i]>c) {//如果有字母的数量超过了它应该有的数量直接===
            printf("===");
            return 0;
        }
        else a[i]-=c;//计算每个字母还要出现几次
    }
    for(i=0;i<k;i++){
        if(x[i]=='?'){
            while(flag==0){
                if(a[d]>0){//一旦出现?,检查每个字母还要替代多少次
                    x[i]=g[d];
                    a[d]--;
                }
                else d++;//如果一个字母出全了,再换下一个字母
                if(x[i]!='?')flag=1;//一旦成功替换,结束while循环,再找下一个?
            }
            flag=0;//结束while循环后把flag初始化
        }   
    }
    print:for(i=0;i<k;i++){
        printf("%c",x[i]);
    }
    return 0;
}
}
4 回复
#2
rjsp2023-10-11 15:15
if(e==0) goto print;//如果没有?直接输出原字符串
这个不对吧,假如我输入 AAAA 的话,……
#3
xyhuuz2023-10-11 15:35
回复 2楼 rjsp
对对对,不小心漏了这点
程序代码:

#include<iostream>
using namespace std;
int main(){
    char x[256];
    int a[4]={0};
    char g[4]={'A','C','G','T'};
    int i,k,c,d=0,flag=0,e=0;
    scanf("%d",&k);
    if((k%4)!=0){//长度不是4的倍数直接===
        printf("===");
        return 0;
    }
    x[k]='\0';
    for(i=0;i<k;i++){
        scanf(" %c",&x[i]);
        if(x[i]=='?') e++;//统计?出现次数
        switch(x[i]){//统计各字母出现次数
            case 'A':a[0]++; break;
            case 'C':a[1]++; break;
            case 'G':a[2]++; break;
            case 'T':a[3]++; break;
        }
    }
    c=k/4;//每个字母应该有的数量
    for(i=0;i<4;i++){
        if(a[i]>c) {//如果有字母的数量超过了它应该有的数量直接===
            printf("===");
            return 0;
        }
        else a[i]-=c;//计算每个字母还要出现几次
    }
    if(e==0) goto print;//这里已经在上面检查了字母的数量是否超过了它应该有的数量,现在的话如果没有?就可以直接输出原字符串
    for(i=0;i<k;i++){
        if(x[i]=='?'){
            while(flag==0){
                if(a[d]>0){//一旦出现?,检查每个字母还要替代多少次
                    x[i]=g[d];
                    a[d]--;
                }
                else d++;//如果一个字母出全了,再换下一个字母
                if(x[i]!='?')flag=1;//一旦成功替换,结束while循环,再找下一个?
            }
            flag=0;//结束while循环后把flag初始化
        }   
    }
    print:for(i=0;i<k;i++){
        printf("%c",x[i]);
    }
    return 0;
}


我把它改到下面应该就可以了,但这不是我主要想提问的,因为假设有这样的字符串,程序并不能给我输出正确答案,比如在input1里面,我实测他给我输出不对,,
#4
rjsp2023-10-11 16:56
回复 3楼 xyhuuz
输入测试样例,你的输出是乱码呀?

我简单写了一个
#include <cstdio>
#include <algorithm>
#include <cassert>

int main( void )
{
    char s[256];
    scanf( "%*u%s", s );

    unsigned a = 0;
    unsigned c = 0;
    unsigned g = 0;
    unsigned t = 0;
    unsigned q = 0;
    for( size_t i=0; s[i]; ++i )
    {
        switch( s[i] )
        {
        case 'A': ++a; break;
        case 'C': ++c; break;
        case 'G': ++g; break;
        case 'T': ++t; break;
        default:  ++q;
        }
    }

    unsigned n = a + c + g + t + q;
    if( n%4!=0 || n/4<std::max({a,c,g,t}) )
        puts( "===" );
    else
    {
        for( size_t i=0; s[i]; ++i )
        {
            if( s[i] == '?' )
            {
                if( a!=n/4 )
                    s[i]='A', ++a;
                else if( c!=n/4 )
                    s[i]='C', ++c;
                else if( g!=n/4 )
                    s[i]='G', ++g;
                else if( t!=n/4 )
                    s[i]='T', ++t;
            }
        }
        assert( a==n/4 && c==n/4 && g==n/4 && t==n/4 );
        puts( s );
    }
}

#5
xyhuuz2023-10-11 18:00
回复 4楼 rjsp

我就是因为感觉没错却出乱码头疼,就这样吧,感谢
1