【牛客网】HJ92 在字符串中找出连续最长的数字串(C++)

HJ92 在字符串中找出连续最长的数字串

题目来源 牛客网 HJ92

描述

输入一个字符串,返回其最长的数字子串,以及其长度。若有多个最长的数字子串,则将它们全部输出(按原字符串的相对位置)

本题含有多组样例输入。

数据范围:字符串长度 1 \le n \le 200 \1≤n≤200 , 保证每组输入都至少含有一个数字

输入描述:

输入一个字符串。1<=len(字符串)<=200

输出描述:

输出字符串中最长的数字字符串和它的长度,中间用逗号间隔。如果有相同长度的串,则要一块儿输出(中间不要输出空格)

输入:
abcd12345ed125ss123058789
a8a72a6a5yy98y65ee1r2
输出:
123058789,9
729865,2
说明:
样例一最长的数字子串为123058789,长度为9
样例二最长的数字子串有72,98,65,长度都为2    

题解代码

这道题的思路很简答,从前往后遍历一遍,遇到字符串就开始计算count,并记录起始位置。最后再把起始位置和子串长度插入一个pair里面。

需要注意的是,这里必须要用pair,因为题目要求中提到了,如果有多个相同长度的数字串,就需要一并输出,并加上最后位的,长度

#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
using namespace std;

//给定一个256字符的字符串,输出内部最长数字子串
bool isNumStr(const char& c)
{
    return (c >= '0' && c <= '9');
}

int main()
{
    string s;//来源
    while(getline(cin, s))
    {
        //cout<<s<<endl;
        //string ret_s;//结果
        vector<pair<int,int>> v;//用来存放数字子串的位置
        int begin = 0;//标记数字串的开始
        int count = 0;//标记长度
        int max = 0, mbegin;//上一次获取到的数据串长度和起始位置
        int flag = 0;//标记位
        for (int i = 0; i < s.size(); i++)
        {
            if (i < s.size() - 1 && isNumStr(s[i]) && isNumStr(s[i + 1]))
            {
                count++;
                if (flag != 1) {
                    begin = i;//说明开始计算了
                    flag = 1;
                }
                //cout<<"i"<<i<<" c"<<count<<" b"<<begin<<endl;
            }
            else if (isNumStr(s[i]))//自己还是数字,但是下一位不是
            {
                count++;
                //cout<<"i"<<i<<" c"<<count<<" b"<<begin<<endl;
            }
            else {
                if (count >= max) {
                    max = count;//最大的长度
                    mbegin = begin;//最大长度的起始位置
                    v.push_back(make_pair(count, begin));
                }
                count = 0;//置零
                flag = 0;
            }

        }

                    
        if (count >= max)
        {//循环结束后还需要一次判断,避免最后一个字符依旧是数字的情况
            max = count;
            mbegin = begin;
            v.push_back(make_pair(count, begin));
        }
        
        for(auto e:v)
        {
            if(e.first==max)
            {
                for(int i = e.second;i<e.second+e.first;i++)
                {
                    cout<<s[i];
                }
            }
        }
        cout<<","<<max<<endl;//结束后统一输出max
    }

    return 0;
}
// 通过全部用例  运行时间4ms 占用内存448KB

做这道题的起因-另外一道题

咳咳,在学校上课的时候遇到了另外一道题目,这道题目只需输出一个最长数字子串就可以了,不需要关心长度相同的问题。

image-20220907101148189

我的思路和HJ92一样,就是遍历找到数字子串的长度和起始位置,然后插入一个新的string再cout进行输出。其中s和ret_s这两个变量都是string

然后我就遇到了“奇葩情况”

image-20220907101233516

我还在本地测试了两次,发现“应该”是不会多打印空格什么的

image-20220907101334619

上图Linux G++,下图VS2019

image-20220907101337868

而我通过了上面的HJ92那道题,说明代码的思路是完全没有问题的,问题就出在输出这里


在结束之后(这道题限时,我没能解决这个问题)我才发现自己是个大笨蛋!

解决方法1:加斜杠0

注意,加endl的方法我已经试过了,也不行

其实在这里,我是有想过加\0的,但是我-加-错-位-置了!!!应该给ret_S加,哼哼啊啊啊啊

image-20220907101739893


解决方法2:直接for打印

这个方法我也没想到,既然我都已经知道起始位置和子串长度了,为啥不直接打印原本string里面的内容呢?直接for打印一下不就行了???

只能说自己对容器的使用还不是很熟悉,知识没学到位啊,哭

QQ图片20220519235547

把自己挂在这里告诫后来者

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慕雪华年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值