自用笔记27——sizeof溢出/continue/数组返回

给定一个字符串 S,返回 “反转后的” 字符串,其中不是字母的字符都保留在原地,而所有字母的位置发生反转。

示例 1:

输入:“ab-cd”
输出:“dc-ba”
示例 2:

输入:“a-bC-dEf-ghIj”
输出:“j-Ih-gfE-dCba”
示例 3:

输入:“Test1ng-Leet=code-Q!”
输出:“Qedo1ct-eeLg=ntse-T!”

提示:

S.length <= 100
33 <= S[i].ASCIIcode <= 122
S 中不包含 \ or "

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-only-letters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

第一次尝试的代码,好像数组溢出了,但是还没有发现在哪里出了问题

char * reverseOnlyLetters(char * S){
    int i=0,j=0,len=sizeof(S);
    char c[101]={0};
    char g[101]={0};
    for(i=len-1;i>=0;i--)
    {
        if((S[i]>=97 && S[i]<=122) || (S[i]>=65 && S[i]<=90) && (j<100))
        {
            c[j]=S[i];
            j++;
        }  
    }
    for(i=0;i<len;i++)
    {
        if(S[i]<65 || (S[i]>90 && S[i]<97))
            g[i]=S[i];
    }
    j=0;
    for(i=0;i<len;i++)
    {
        if(g[i]==0 && j<100)
        {
            g[i]=c[j];
            j++;
        }
    }
    return g;


}

换种思路后的代码:
从数组的头和尾一起开始查找,如果是字母则交换头和尾的位置,如果是符号则原位不动。
更具体的实现就是从S[i]的前和后一起开始判断,如果是符号,就原位不动放进T[i],如果是字母则反向放入T数组。这样同时从前后开始能节省程序时间。

char *reverseOnlyLetters(char *S){
    int i=0,length=0,j=0;
    while(S[length]!=0) length++;
    char T[length+1];
    T[length]=0;
    i=0;
    j=length-1;
    while(i<=j)
    {
        if(!(S[i]>='A' && S[i]<='Z' || S[i]>='a' && S[i]<='z'))
        {
            T[i]=S[i];
            i++;
            continue;
        }
        if(!(S[j]>='A' && S[j]<='Z' || S[j]>='a' && S[j]<='z'))
        {
            T[j]=S[j];
            j--;
            continue;
        }
        T[i]=S[j];
        T[j]=S[i];
        i++;
        j--;
    }
    S=T;
    return S;       
    
}

使用sizeof会造成数组溢出,即length=sizeof(S);之后使用S[length]=0;会造成数组溢出;
而使用while(S[length] length++;)就可以避免这种情况,暂时还没找到原因,反正记住这一点就行了。

另外continue是跳出本次循环,即不再执行后面的步骤,直接而开始判定while括号的条件,常常与if搭配;
break是直接跳出所有循环,不再判定执行循环,对于多层的循环一层一层地跳。

再就是函数里声明的数组无法返回,函数结束后数组直接被清空,所以要返回数组必须用指针或者借助修改主函数的数组内容的方法返回。

当弄明白以上三点后第一次代码的也就可以修改成功:
我一开始的思路:
第一步:将S数组中的字母全部反向放入c数组中;
第二步:将S数组中的符号全部正向放入g数组中,符号的位置放符号,字母的位置全部放“0”;
第三步:把g数组中为0的元素用c数组的元素按顺序替换。
这种方法虽然思路简洁,但是程序时间过长。

char * reverseOnlyLetters(char * S){
    int i=0,j=0,len=0;
    while(S[len]!=0) len++;
    char c[len+1];
    char g[len+1];
    c[len]=0;g[len]=0;
    for(i=len-1;i>=0;i--)
    {
        if((S[i]>=97 && S[i]<=122) || (S[i]>=65 && S[i]<=90))
        {
            c[j]=S[i];
            j++;
        } 
    }
    for(i=0;i<len;i++)
    {
        if(S[i]<65 || (S[i]>90 && S[i]<97))
            g[i]=S[i];
        else
            g[i]=0;
    }
    j=0;
    for(i=0;i<len;i++)
    {
        if(g[i]==0)
        {
            g[i]=c[j];
            j++;
        }
    }
    S=g;
    return S;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值