L1-025. 正整数A+B 分析和优化

2021.7.16 

先贴一下题目

题的目标很简单,就是求两个正整数AB的和,其中AB都在区间[1,1000]。稍微有点麻烦的是,输入并不保证是两个正整数。

输入格式:

输入在一行给出AB,其间以空格分开。问题是AB不一定是满足要求的正整数,有时候可能是超出范围的数字、负数、带小数点的实数、甚至是一堆乱码。

注意:我们把输入中出现的第1个空格认为是AB的分隔。题目保证至少存在一个空格,并且B不是一个空字符串。

输出格式:

如果输入的确是两个正整数,则按格式A + B = 和输出。如果某个输入不合要求,则在相应位置输出?,显然此时和也是?

输入样例1:

123 456

输出样例1:

123 + 456 = 579

输入样例2:

22. 18

输出样例2:

? + 18 = ?

输入样例3:

-100 blabla bla...33

输出样例3:

? + ? = ?

 上一下自己的渣渣代码

#include<stdio.h>
#include<string.h>
char a[100005],b[100005];
int main()
{
    scanf("%s",a);//scanf不录入空格,遇空格,Tab,回车停止
    getchar();//吃空格
    gets(b);//gets可以录入空格 Tab
    int lena,lenb,ak=1,bk=1,numa,numb;
    lena=strlen(a);
    lenb=strlen(b);
    for(int i=0; i<lena; i++)//这种算字符串的方法有点笨,下面的代码可以优化的。
    {
        int k;
        k=(int)(a[i]-'0');
        if(k>9||k<0)
        {
            a[0]='?';
            a[1]='\0';//可以直接用strcpy(a,"?");
            ak=0;
            break;
        }
    }

    for(int i=0; i<lenb; i++)
    {
        int k;
        k=(int)(b[i]-'0');
        if(k>9||k<0)
        {
            b[0]='?';
            b[1]='\0';
            bk=0;
            break;
        }
    }
    if(ak&&bk)
    {
        numa=atoi(a);//atoi函数用于字符串型转整型
        if(!numa||numa>1000)//负数开头就已经被处理,只需要注意0和大于1000的情况
        {
            a[0]='?';
            a[1]='\0';
            ak=0;
        }
        numb=atoi(b);
        if(!numb||numb>1000)
        {
            b[0]='?';
            b[1]='\0';
            bk=0;
        }
        if(ak&&bk)
        {
            printf("%s + %s = %d",a,b,numa+numb);
        }
        else
        {
            printf("%s + %s = ?",a,b);
        }
    }
    else
    {
        printf("%s + %s = ?",a,b);
    }
}

计算过程什么的倒是没什么问题,主要是感觉自己的代码有点冗杂,于是就查了一下其他人的做法

就有了下面的一段代码(链接在后面,谢谢大佬)

    #include<stdio.h>
    int convert(const char *str)
    {
        int sum=0;
        int i;
        for(i=0;str[i]!='\0';i++)
        {
            if(str[i]>='0' && str[i]<='9')
                sum=sum*10+str[i]-'0';
             else
                return -1;
 
        }
        if(sum>=1 && sum<=1000)
            return sum;
        else
            return -1;
    }
    int main()
    {
        char A[10000],B[10000];
        int a,b;
        scanf("%s ",&A);//%s后面加了一个空格,不用getchar()
        gets(B);
        a=convert(A);
        b=convert(B);//通过编写的函数计算
        if(a==-1)
            printf("? + ");
        else
            printf("%d + ",a);
         if(b==-1)
            printf("? = ");
        else
            printf("%d = ",b);
        if(a==-1||b==-1)
            printf("?\n");
        else
            printf("%d\n",a+b);//这一大段都比我的要简洁有条理的多
        return 0;
 
    }

看完大佬的做法后,自己也在考虑是不是可以利用atoi函数让代码更加简洁一些,于是就有了下面一段代码

#include<stdio.h>
#include<string.h>
char a[100005],b[100005];
int main()
{
    scanf("%s ",a);
    gets(b);
    int numa,numb;
    numa=atoi(a);
    numb=atoi(b);
    if(numa<1||numa>1000)/*atoi函数会计算负数,所有需要考虑到小于1和大于1000的情况(非法输入返回0)*/
    {
        numa=0;
        strcpy(a,"?");
    }
    if(numb<1||numb>1000)
    {
        numb=0;
        strcpy(b,"?");
    }
    if(numa&&numb)
    {
    printf("%d + %d = %d",numa,numb,numa+numb);
    }
    else
    {
    printf("%s + %s = ?",a,b);
    }
}

但是atoi函数有一个小缺陷吧,遇见空格之后的数字就不会再处理(之后发现开头的空格也不会处理)

遇上下面这种情况就很尴尬

 b数组里面开头为数字后遇见空格后面的就不会再处理,算是一个缺陷,可惜(悲

 综上所述,基本上可以确定大佬的代码为最优解(再次赞美大佬

大佬代码出处:https://blog.csdn.net/qq_31359295/article/details/51931937?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162640089216780255257763%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=162640089216780255257763&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-51931937.first_rank_v2_pc_rank_v29&utm_term=l1-025&spm=1018.2226.3001.4187

atoi函数解析:https://blog.csdn.net/weixin_40332490/article/details/105104229?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162639970716780357215255%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=162639970716780357215255&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-2-105104229.first_rank_v2_pc_rank_v29&utm_term=atoi&spm=1018.2226.3001.4187

https://blog.csdn.net/weixin_51333606/article/details/114948652?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162639970716780357215255%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=162639970716780357215255&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-114948652.first_rank_v2_pc_rank_v29&utm_term=atoi&spm=1018.2226.3001.4187

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值