利用C++的STL优雅的完成此题。
解题思路
这是一道新手入门的题目,但是有很多细节。
做法我们分情况讨论下:
对于整数,去除前后的0并直接反转
对于百分数,删去百分号后按照整数的套路即可
对于分数,找到
/
并以他为界分割成两个字符串,分别去除前后的0并反转,然后再合并对于小数,同上,不过要将分隔符换成
.
然后输出即可。
这样看起来,整个题目也并没有那么复杂了。
程序实现
根据上面的归纳,可以看出整个程序无非就几个步骤:
去除前后的0
判断字符串是属于分数,还是小数?又或者是百分数?
将字符串倒置
分割字符串
为了简单与优雅,我们可以直接调用STL的函数解决。
字符串类型的判断
判断字符串的类型,我们可以直接在字符串中查找符号来判断,如果既没有/
,也没有.
,也没有%
,那肯定就是整数了。
在String类中间,内置了一个源String.find(待查找的字符串)
的函数,若找到了则返回字符的位置,否则返回string::npos
,我们直接拿来用就好。
字符串的倒置
同样的,在STL中内置了一个很好用的反转函数:reverse(起始迭代器,结束迭代器)
,我们同样可以直接拿来用。
迭代器怎么获取?直接待反转String.begin()
和待反转String.end()
即可。
分割字符串
在其他的语言中,字符串类型一般都内置了split这样的函数,可C++好像是一个特例。
那就自己实现吧。
在字符串类中,还有一个好用的函数:待分割String.substr(起始位置,取出的长度)
,可以直接取出给定起点和长度的子字符串。
首先利用find函数找到符号的位置,记录在变量pos中。
然后提取前半部分:起始位置当然是0,长度为pos,这样取到的就是 0~pos-1 的子字符串。
接着提取后半部分:起始位置是pos+1,长度为总长度-pos,这样取到的就是 pos+1~总长度 的子字符串。
去0?
这个就实在没有库函数可以利用了,STL也不可能提供这样“奇怪”的库函数。
当然,自己写一个也很简单。
弄个循环,如果第一位是0,那就删掉第一位,然后重新判断。
同理,从后往前找即可,一直删到最后一位不为0即可。
注意,这里有个小坑,如果“0000”这样的,那么就会返回“”这样的空字符串,显然至少需要保留一个0。那我们判断一下就好。
AC代码
#include <bits/stdc++.h>//万能头文件
using namespace std;
string zero(string o)//辅助函数,用于去除字符串前置的0与后置的0
{
while (o[o.length()-1]=='0')//去后0
o=o.substr(0,o.length()-1);
while (o[0]=='0')//去前0
o=o.substr(1,o.length()-1);
return o==""?"0":o;//一个fix,避免全是0就给了个空字符串
}
int main()
{
string o;
cin >> o;
if (o.find(".")!=string::npos)//小数
{
string a=o.substr(0,o.find(".")),b=o.substr(o.find(".")+1,o.length()-o.find("."));
a=zero(a);
b=zero(b);
reverse(a.begin(),a.end());
reverse(b.begin(),b.end());
cout << a << "." << b;
}
else if (o.find("\%")!=string::npos)//百分数
{
string a=o.substr(0,o.find("\%"));
a=zero(a);
reverse(a.begin(),a.end());
cout << a << "\%";
}
else if (o.find("/")!=string::npos)//分数
{
string a=o.substr(0,o.find("/")),b=o.substr(o.find("/")+1,o.length()-o.find("/"));
a=zero(a);
b=zero(b);
reverse(a.begin(),a.end());
reverse(b.begin(),b.end());
cout << a << "/" << b;
}
else//啥都找不到,自然是整数
{
o=zero(o);
reverse(o.begin(),o.end());
cout << o;
}
return 0;
}