题目指路:P1553 数字反转(升级版)
题目分析:
四种情况:小数,分数,百分数,整数。
- 整数就是正常的反转。(除非除了0没有别的数,那么只保留1个0)
- 百分数的分子一定是整数,百分数只改变数字部分。(实际上只是整数反转多了一个%)
- 小数反转是把整数部分的数反转,再将小数部分的数反转,不交换整数部分与小数部分,小数新数的末尾不为0(除非小数部分除了0没有别的数,那么只保留1个0);
- 分数反转是把分母的数反转,再把分子的数反转,不交换分子与分母,不约分;(其实先反转除号左边再反转除号右边效果相同,只不过要注意除号左边可能是0)
思路:
1.可以看出这个题最重要的是如何看待字符串,整数字符串中只存在数字,而小数,分数,百分数字符串中包含有其他字符(后统称符号)。对于有符号的可以以符号为分界简单的将输入数据从符号开始分割为两个数组。我们可以用一个识别字符是否为数字的函数实现此功能。
2.从题意可以看出两个部分的反转是独立的,那么我们可以写一个反转函数来实现所有分割数组的反转。
3.百分号后面的数组不需要输出,需要特判。
4.小数新数的末尾不为0,举例来说若输入数据为600.060,则结果应为6.6。如果是小数需要特别去掉这个末尾的零。
5.当输入为不为分数右边(即整数或百分数或小数两部分或分数左边)且全为0的情况,需要用一个函数判断,并且只输出一个0;
本蒟蒻不会stl函数c/c++也学的很渣,所以要用什么函数只能自己写且代码写的超复杂,但是能AC本蒟蒻就很开心了QAQ。
本蒟蒻的写法:
#include <bits/stdc++.h>
using namespace std;
int l,f,j,i,k,p,m,ii,cd,js,num;
char a[25],t,n[2],c[25],fh,sr[50];
int isnum(char x)//此函数判断输入字符是否为符号
{
if(x>='0'&&x<='9')
return 1;
else
return 0;
}
void fz (char s[25])//此函数用来反转分割的数组
{
f=j=0;
int b[25];
memset(b,0,sizeof(b));
l=strlen(s);
for(i=l-1;i>=0;i--)
{
b[j]=s[i];
j++;
}
if(fh=='.')//特判小数,若末尾为0删掉
{
while(b[j-1]=='0')
{
b[j-1]='\0';
j--;
}
}
for(i=0;i<j;i++)
{
if(b[i]!='0')
f=1;
if(f==1)
printf("%c",b[i]);
}
}
int iso(char w[50])//判断是否数组内元素全为0
{
int x,y=0,g;
g=strlen(w);
for(x=0;x<g;x++)
{
if(w[x]=='0')
y++;
}
if(y==g) return 1;
else return 0;
}
int main()
{
p=m=0;
gets(sr);
cd=strlen(sr);
for(js=0;js<cd;js++)
{
if(isnum(sr[js]))
{
if(k==0)
{a[p]=sr[js];
p++;
}
else//以符号为界分割字符串
{
c[m]=sr[js];
m++;
}
}
else
{
k=1;//记录是否有符号
fh=sr[js];
}
}
if(iso(a))
{printf("0");}
else
{fz(a);}
if(k==1)
{
printf("%c",fh);
if(iso(c)&&fh!='%')//特判百分数
printf("0");
else if(m!=0)
fz(c);}
return 0;
}
本蒟蒻觉得我写的肯定是解此题最麻烦的方法了,欢迎大佬指正。