待提取字符串:EHT measured the black hole’s mass to be approximately 6.5 billion solar masses and measured the diameter of its event horizon to be approximately 40 billion kilometres (270 AU; 0.0013 pc; 0.0042 ly)
心得:主要的难点是出现(单词,或者(数字的情况。策略是判断每个子串的第二个字符。一开始提取子串的操作让后来的判断简洁了很多。不仅根据本题出现的(数字情况,我还对本题没出现的(字母情况进行了处理,让功能更加完善,虽然还是有不少有待优化的地方,限于时间做不到完美了。单步调试了很多次,单步调试能发现很多看似正确实则出错的地方(尤其是判断和循环语句)单步调试yyds!通过单布调试找出了最后一个字符串输出不了的原因:因为最后一个不是空格无法提取子串,解决方法是手动加了一个空格,当然也可以重新定义一个添加一个空格的字符串,没啥必要。好的习惯是在选择和循环语句中多用括号,不然分支或条件一多就容易乱
输出结果:
#include <iostream>
using namespace std;
#include<string>
#include<vector>
int main()
{
int pos1=-1, pos2=0,flag1=1,flag2,countw=0,counti=0,countf=0;
vector<char>word;
vector<char>in;
vector<char>fl;
vector<char>po;
string blackHole = "EHT measured the black hole's mass to be approximately 6.5 billion solar masses and measured the diameter of its event horizon to be approximately 40 billion kilometres (270 AU; 0.0013 pc; 0.0042 ly) ";
for (int i = 0; i < blackHole.length()+1; i++)//上面一行字符串手动+了一个空格,不然最后一个子串没法判断
{
if (blackHole[i] == ' ')
{
pos2 = i;
string temp = blackHole.substr(pos1 + 1, pos2-pos1);//先把子串取出来再 判断
if (temp[0] <= '9' && temp[0]>='0')//判断是否为数字
{
for (int j = 0; j < pos2-pos1;j++)//遍历子串,判断是整数还是浮点数,此处有个边界判断遗留问题
{
if (temp[j] == '.')//判断是浮点数的标志,否则是整数
{
flag1 = 0;
break;
}
}
if(flag1==0)//浮点数
{
if (temp[pos2 - pos1 - 2] < '0' || temp[pos2 - pos1 - 2] > '9')//判断数字末是否为标点
{
for (int i = 0; i < pos2 - pos1 - 2; i++)//若是,长度-2,再加一个空格
{
fl.push_back(temp[i]);
}
fl.push_back(' ');
pos1 = pos2;
flag1 = 1;
countf++;
}
else {
for (int i = 0; i < pos2 - pos1; i++)
{
fl.push_back(temp[i]);
}
pos1 = pos2; flag1 = 1;
countf++;
}
}
//否则是整数
else {
if (temp[pos2 - pos1 - 2] < '0' || temp[pos2 - pos1 - 2] > '9')//判断数字末是否为标点
{
for (int i = 0; i < pos2 - pos1 - 2; i++)//若是,长度-2,再加一个空格
{
in.push_back(temp[i]);
}
in.push_back(' ');
pos1 = pos2;
counti++;
}
else
{
for (int i = 0; i < pos2 - pos1; i++)
{
in.push_back(temp[i]);
}
pos1 = pos2;
counti++;
}
}
}
//否则很可能是单词
else if(temp[0]>='a'&& temp[0] <= 'z'|| temp[0] >= 'A' && temp[0] <= 'Z')//判断首是否为字母
{
if (temp[pos2 - pos1 - 2] < 'A' || temp[pos2 - pos1 - 2] > 'z'|| temp[pos2 - pos1 - 2]>'z'&& temp[pos2 - pos1 - 2]<'a')//判断词末是否为标点
{
for (int i = 0; i < pos2 - pos1 - 2; i++)//若是,长度-2,再加一个空格
{
word.push_back(temp[i]);
}
word.push_back(' ');
countw++;
}
else
{
for (int i = 0; i < pos2 - pos1; i++)
{
word.push_back(temp[i]);
}
countw++;
}
}
else//如果第一个不是字母或数字,可能为左括号,从第二个开始判断。
if (temp[1] <= '9' && temp[1] >= '0')
{
for (int j = 1; j < pos2 - pos1; j++)//遍历子串,判断是整数还是浮点数,此处有个边界判断遗留问题
{
if (temp[j] == '.')//判断是浮点数的标志,否则是整数
{
flag1 = 0;
break;
}
}
if (flag1 == 0)//浮点数情况
{
for (int i = 1; i < pos2 - pos1; i++)
fl.push_back(temp[i]);
pos1 = pos2; flag1 = 1;
countf++;
}
//否则是整数
else {
for (int i = 1; i < pos2 - pos1; i++)
{
in.push_back(temp[i]);
}
pos1 = pos2;
counti++;
}
}
//否则是单词
else if (temp[1] >= 'a' && temp[1] <= 'z' || temp[1] >= 'A' && temp[1] <= 'Z')//判断首是否为字母
{
if (temp[pos2 - pos1 - 2] < 'a' || temp[pos2 - pos1 - 2] > 'z')//判断词末是否为标点
{
for (int i = 1; i < pos2 - pos1 - 2; i++)//若是,长度-2,再加一个空格
{
word.push_back(temp[i]);
}
word.push_back(' ');
countw++;
}
else//若不是,正常输入
{
for (int i = 1; i < pos2 - pos1; i++)
{
word.push_back(temp[i]);
}
countw++;
}
}
pos1 = pos2;
}
}
for (vector<char>::iterator it = word.begin(); it != word.end(); it++) {
cout << *it;
}
cout << endl;
cout << "单词个数:"<<countw << endl<<endl;
for (vector<char>::iterator it = in.begin(); it != in.end(); it++) {
cout << *it;
}
cout << endl;
cout << "整数个数:"<< counti<<endl<<endl;
for (vector<char>::iterator it = fl.begin(); it != fl.end(); it++) {
cout << *it;
}
cout << endl;
cout << "浮点数个数:"<<countf<<endl<<endl;
system("pause");
return 0;
}