【C++】有问题的【说反话】

首先这是自己写的代码:

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#define MAX_N 100
using namespace std;
int main()
{
    char str[MAX_N];
    cin.getline(str,MAX_N);
    int len=strlen(str);
    int space_num=1;
    int space_i[MAX_N];
    space_i[0]=0;
    for(int i=0; i<len; i++)
    {
        if(str[i]==32) space_i[space_num++]=i;
    }
    space_i[space_num]=len;
    int j=space_i[space_num-1]+1;
    int p=space_i[space_num];

    int jj=space_num-1;
    int pp=space_num;
    for(int k=0; k<space_num; k++)
    {
        if(k==space_num-1)printf(" ");
        for(int i=j; i<p; i++)
        {
            printf("%c",str[i]);
        }
            j=space_i[--jj];
            p=space_i[--pp];
    }

    return 0;
}

本地运行效果:

 看起来没毛病,gets函数在平台上不可以AC了,换了cin.getline(str,len)函数,遇到回车结束输入。

一开始按照要求定义MAX_N为80,结果四个测试点只对了一个,三个答案错误,把这个改成90,就变成两个答案错误了。

题目说:在一行内给出总长度不超过 80 的字符串。

有点糊···但是看了很多例题定义的都比他说的大10.

然后我有些困,脑子转不起来了,怎么想都想不出来哪两个错误在哪,我又测试了几个随便输几个句子,都没问题呀看起来。

 

然后看到另外两种写法:

①使用while```scanf()不用特意去判断何时输入结束,定义二维数组,利用scanf不用自己判断空格,但是要使用ctrl+z和回车结束输入

②抛弃gets函数的前提下,我上面是用了cin.getline没毛病,但是逻辑可以有区别:

我的逻辑是一个单词一个单词的输出,里面看到有个二层for循环,一层循环结束重新改变内层循环的起始和结束。

书上的逻辑:一股脑接收了之后,定义一个二维数组,将字符串按照空格分隔自己对应存进去,数组中:遇到空格存在行的结尾存'\0',在再换行循环存就好了。

 

①代码:不得不说用了while scanf真的是看起来清爽多了 搭配数组,逻辑清晰,看起来真的很舒爽。

#include <cstdio>

int main()
{
    char str[90][90];
    int num=0;
    while(scanf("%s",str[num])!=EOF){
            num++;
    }
    for(int i=num-1;i>=0;i--)
    {
        printf("%s",str[i]);
        if(i>0)printf(" ");
    }
    return 0;
}

这个代码,我感觉我以后可能会记不住的点是,他很巧妙的利用了scanf函数,和二维数组的地址表示方法,通过加1不断向下。希望勤能生巧吧! 

运行结果:AC

 

②老老实实,不使用while scanf也不能使用gets了之后的写法:

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
    char ans[90][90];
    char str[90];
    cin.getline(str,90);//cin.getline(str,90)
    int len=strlen(str),r=0,h=0;
    for(int i=0; i<len; i++)
    {
        if(str[i]!=' ')
        {
            ans[r][h++]=str[i];//h++
        }
        else
        {
            ans[r][h]='\0';//0
            r++;
            h=0;//列要置零,脑海中有图
        }
    }
    for(int i=r; i>=0; i--)
    {
        printf("%s",ans[i]);
        if(i>0)printf(" ");//注意是i>0不是r
    }
    printf("\n");
    return 0;
}

AC:

 

最后看到了一篇博客,应该和我一开始自己写的思路是一样的,都是每个单词输出去,找到空格的位置,但是他的写法比我自己的高大上多了,他没有像我那样罗里吧嗦的,直接一个二层循环倒着找,找到空格就停下,当前位置和最后位置之间是一个单词,然后更新最后的位置为当前的位置,接着往前找,这样边找边输出。关于空格的问题也处理的很优雅,定义了一个bool变量先为true,就是为了让第一个单词前不输出空格。然后在输出第一个字母的时候就同时置为false这样之后碰到空格就输出空格,很优秀。

链接:https://blog.csdn.net/qq_36525099/article/details/86631881

代码:

#include <stdio.h>
#include <string.h>
#include<iostream>
 
using namespace std;
 
int main(){
    char s[90];
    cin.getline(s,90);
    int len=strlen(s);
    int last=len;
    bool first=true;
    for(int i=len-1;i>=-1;i--){
        if(i==-1 || s[i]==' '){
            if(first)
                first=false;
            else
                printf(" ");
            for(int j=i+1;j<last;j++)
                printf("%c",s[j]);
            last=i;
        }
    }
}

本来想回过头再完善自己原来的写法,结果看得很晕胡 。

原来的思想是把所有空格的位置保存下来,连同最前面的一个字母前的位置,和最后面一个字母后面的位置。然后再和上面一样每一个单词按照两层for循环输出。

。。看得要吐了。

 

总而言之,利用while scanf是代码量最少的,看起来最优秀的,脑子不用转太多弯弯,但是要巧妙的运用二维数组的表示方法和scanf函数的返回值,何时结束。

 

希望熟能生巧!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值