利用 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) { while (o[o.length()-1]=='0') o=o.substr(0,o.length()-1); while (o[0]=='0') o=o.substr(1,o.length()-1); return o==""?"0":o; } 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; }
|