翻转数字
众所周知。翻转数字是一个很经典的题目(为什么经典,还不是太菜被卡了很长时间) 都说了是pro版,当然要颠覆经典。
题目是这样的:给定一个数,请将该数各个位上数字反转得到一个新数。要求:这个数可以是小数,分数,百分数,整数。整数反转是将所有数位对调;小数反转是把整数部分的数反转,再将小数部分的数反转,不交换整数部分与小数部分;分数反转是把分母的数反转,再把分子的数反转,不交换分子与分母;百分数的分子一定是整数,百分数只改变数字部分。整数新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零;小数新数的末尾不为0(除非小数部分除了0没有别的数,那么只保留1个0);分数不约分,分子和分母都不是小数。没有负数。
刚开始,我就用最古老的方法,什么记录数组啊,什么标志记录啊,最后都不是满分,只有65分(有个卵用)。最后发现这种原始方法在小数那一关就卡不过去。然后就果断放弃,开始youtube起来(果然老废物)。但好在我19年曾经在学校图书馆吃过早饭,而且学会了骑电瓶车。(这tm和题目有什么关系) 所以,就瞎弄了一下STL和String。(这个愣转弯是真没想到)
上代码:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
string reverse_1(string s)
{
int count_0 = 0; //记录0的个数
reverse(s.begin(), s.end());
for (auto i : s)
if (i == '0') count_0++; //统计前导0的个数
else break;
s.erase(s.begin(), s.begin() + count_0); //擦除前导0
return (s != "" ? s : "0"); //防止其出现全擦除导致错误,特判
}
string deleteback(string s)
{
int count_0 = 0;
for (int i = s.size() - 1; i >= 0; i--)
{
if (s[i] == '0') count_0++; //统计后导0
else break;
}
s.erase(s.end()-count_0, s.end()); //擦除后导0
return (s != "" ? s : "0"); //特判
}
int main()
{
string s;
cin >> s;
if (s.back() == '%') //若符号为%,仅需将其前面的前导的0去除并翻转输出
{
cout << reverse_1(s.substr(0, s.size() - 1)) << "%" << endl;
return 0;
}
for (auto i : s)
{
string left, right;
if (i == '/')
{
left = s.substr(0, s.find("/"));
right = s.substr(s.find("/") + 1);
cout << reverse_1(left) << '/' << reverse_1(right) << endl;
return 0;
}
if (i == '.')
{
left = s.substr(0, s.find('.'));
right = s.substr(s.find('.') + 1);
cout << reverse_1(left) << '.' << deleteback(reverse_1(right)) << endl;
return 0;
}
}
cout << reverse_1(s) << endl;
}
书归正传:之前的方法没有成功的原因是因为在判断小数的 后导0时,没有处理原数位xxxx.0的情况,也不好处理这种情况。同时没有注意到特判的错误情况。
运行结果:
0 条评论