题目链接
题目描述与示例
读入一个字符串str,输出字符串str中的连续最长的数字串
输入描述
每个测试输入包含1个测试用例,一个字符串str,长度不超过255。
输出描述
在一行内输出str中里连续最长的数字串。
示例
输入:
abcd12345ed125ss123456789
输出:
123456789
解题思路
题目分析
这个题目比较简单,就是给你一段字符串,把这个字符串里最长的数字串拿出来就行。
个人思路
- 创建一个vectors对象保存数字串
- 遍历字符串时遇到第一个数字字符停下
- 调用函数找到当前数字串结束位置
- 通过string的构造函数以及数字串开始和结束位置构造一个临时对象保留当前数字串,并用count保存下最大数字串的长度,如果当前数字串长度大于count则pop掉s的数据然后将当前数字串插入到s并且更新count。
需要注意的是,第一个数字串插入前的pop操作可能会因为s为空出错,所以提前push了一个s1进去,后面也可以用它判断是否为没有数字串的字符串甚至是空串。
代码展示
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int Isnumber(const string &s,size_t begin)
{
size_t end=begin+1;
for(;end<=s.size();end++)
{
//字符串中的数字是以字符为标志的,不能直接与整型的0-9作比较
if(s[end]<'0' || s[end]>'9')
break;
}
return end;
}
int main()
{
string s1;
getline(cin,s1);
vector<string> s;
size_t count=0;
//提前插入一个数据
//1、防止空内容pop
//判断是否为没有数字串的字符串甚至空串
s.push_back(s1);
for(size_t i=0;i<s1.size();i++)
{
if(s1[i]>='0' && s1[i]<='9')
{
//找到数字串结束的位置
size_t tmp=Isnumber(s1,i);
if(tmp-i>count)
{
string s2(s1,i,tmp-i);
s.pop_back();
s.push_back(s2);
count=tmp-i;
}
//i-tmp之间的已经确定是数字串并且已经保留,无需再判断,直接跳过
i=tmp;
}
}
//如果s中的数据和s1还是一样说明没有执行到前面的pop操作,即没有发现数字串
if(s[0]==s1)
cout<<"no number string";
else
cout<<s[0];
return 0;
}
题解
题解的思路我理解的大致如下:
- 使用一个两个string对象,一个cur保存获取到的数字串,一个res保存最长的数字串
- 遍历字符串,遇到0-9的字符开始对cur串进行追加
- 遇到不是0-9字符时说明cur中已经保存了数字串,比较cur和res的length,如果cur更大,就将res内容修改为cur中的数字串,否则清空cur(便于保存下一个数字串)
代码如下:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str,res,cur;
cin>>str;
//特别注意!!!!
for(int i=0;i<=str.length();i++)
{
if(str[i]>='0' && str[i]<='9')
cur+=str[i];//+=操作符重载,作用相当于push_back函数
else
{
if(res.length()<cur.length())
res=cur;
cur="";//相当于clear操作,清空cur里面的数据
}
}
cout<<res;
return 0;
}
在上述代码中有一个特别需要注意的地方就在与
for(int i=0;i<=str.length();i++)
一般来讲我们无论遍历string或者vector对象是判断条件都会是小于等于size或者length不让其访问到末尾的结束符号,但是在这个地方如果不访问到末尾结束符的话,会导致一种边缘情况出错:
即当最长的数字串在字符串末尾时,虽然cur已经保存下来了当前的数字串,但由于没有进入else的length判断导致res还没有获取到cur的内容,所以这个地方访问末尾结束符的目的就是为了让程序可以进入到else中的length判断,从而排除这个边缘情况错误。