说实话好像很简单的样子,因为我并不需要真正地把这个东西反转,只需要用一个字符串存储,然后倒着打印出来就好了。
思路:
1.scanf%s读取
2.向后遍历,看下一位
如果是’\0’
说明是整数,此时记录当前下标
flag=0&&并且是‘0’,不打印,
如果不是‘0’,打印,flag=1即可。
如果是’.’
记录此时的位置
把之前的反转打印出来
然后继续遍历,找到’\0’,再把小数点之后,‘\0’之前的反转打印出来,
特殊,如果全是0,那么就要把0也打印出来
如果是’/’
把之前的反转打印出来,再把/之后,’\0’之前的反转打印出来
如果是’%’
把之前的反转打印出来,加上%
遇到的错误。
1.整合时候出现了问题,当在结尾的时候,由于没有进行判断,所以多打印了一次
2.输出百分号需要printf("%%")需要输出两个百分号才行。
3.处理小数部分的时候,利用flag记录出现的第一个非零数字位置,一旦出现非零数字,用flag记录后应该立刻break,不然flag将会一直向后记录
最后输出的时候,也应该判断一下flag不等于0,不然就算全是0,还会再输出一边。
现在遇到的问题:
1.分数模式多输出了一次’/'和非去零反转分子
。。忘了更新start值了。
没想到只得到了75分,说明还有其他特殊情况我没考虑到,我日。
再审一遍题目,
如果数字全是0的话,需要输出0啊。
好吧,这道题算是给我一个教训:
千万不要小看一道看似十分简单的题目,因为一道题目越简单,他需要的判断和细节也就越多,而细节一多,你的代码就很容易出错
总结错误点:
1.打印百分号%%
2.start更新
3.小数部分反转和其他数字的不同之处
4.如果数字全为0,那么需要进行的操作
5.分支输出别忘了判断条件
附代码:
#include<stdio.h>
char str[30];
int start=0;//start用于标记反转区间的范围
void reverse(int st,int end,int mode);
int main()
{
//输入
scanf("%s",str);
for(int i=0;;i++)//别忘了终止条件
{
if(str[i+1]=='\0')//说明终止了
{
if(start==0)
{
reverse(start,i,0);//打印出来,最后一个参数,相当于不保留零
}
else if(str[start-1]=='.')
{
reverse(start,i,1);
}
else if(str[start-1]=='/')
{
// printf("输出分子:");
reverse(start,i,0);
}
break;
}
if(str[i+1]=='.')//小数
{
reverse(start,i,0);
start=i+2;
printf(".");//等一下再处理
}
if(str[i+1]=='/')
{
// printf("输出分母:\n"); //经测试进行了一次。
reverse(start,i,0);
start=i+2;
printf("/");
}
if(str[i+1]=='%')
{
reverse(start,i,0);
printf("%%");
break;//直接结束了。
}
}
}
void reverse(int st,int end,int mode)
{
int flag=0;
if(mode==0)
{
for(int i=end;i>=st;i--)//打印
{
if(str[i]=='0'&&flag==1)//见过才要打印
{
printf("%c",str[i]);
}
else if(str[i]!='0')
{
flag=1;
printf("%c",str[i]);
}
}
if(flag==0)//说明从头到尾没遇到过非零数字,那么这个就是0
{
printf("%c",'0');
}
}
else
{
for(int i=st;i<=end;i++)//正向看0
{
//如果全是0
if(i==end&&flag==0)//flag==0说明没遇到过非零数字
{
printf("%c",'0');
}
else if(str[i]!='0')
{
flag=i;//用i记录出现的第一个非0数字位置
break;
}
}
if(flag!=0)
{
for(int i=end;i>=flag;i--)
{
printf("%c",str[i]);
}
}
}
}