P1553 数字反转(升级版)
作者:互联网
思路比较清晰,但是有许多的细节需要处理,这里我们用到字符串处理的相关知识,第一次尝试如下,但是出现了乱码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main(){
char a[30],b[30];//分别输入字符串数组和输出新的字符串数组
int flag=1,index=-1,len,f,g;
cin>>a;//直接输入即可,但是中间不能有空格,换行符,还好本题没有
len=strlen(a);// cstring 头文件中的计算字符串实际长度的函数,与预设的数组空间无关,数组空间函数用相同头文件下的 sizeof() 函数
for(int i=0;i<len;i++){
// flag==1 代表整数(字符串)类型
if(a[i]=='.'){
flag=2;// flag 为 2 时表示浮点数
index=i;//记录小数点位置
break;//找到符号位就跳出循环
}
else if(a[i]=='/'){
flag=3;
index=i;
break;
}
else if(a[i]=='%'){
flag=4;
//不必记录百分号的位置了,显而易见
break;
}
else;//空语句
}
if(flag==1){//处理整型
f=0;
if(len==1 && a[0]=='0')
b[0]='0';//单独考虑为 0 情况
else{
for(int i=len-1;i>=0;i--){
if(a[i]=='0' && f==0);//舍弃 0
else{
b[f]=a[i];//将有效的数据存入数组 b
f++;
}
}
}
for(int i=0;i<strlen(b);i++)
cout<<b[i];//输出新的整型
}
//注意!注意!这里输出整型时出现了乱码!(如下输出所示)事与愿违(你知道为什么吗?)
else if(flag==2){
f=0;
if(index==1 && a[0]=='0')
b[0]='0';//小数点之前只有一个 0 时
else{
for(int i=index-1;i>=0;i--){
if(a[i]=='0' && f==0);
else{
b[f]=a[i];
f++;//存放有效的小数点之前的数
}
}
}
b[f]='.';//存放小数点
g=f+1;//开始处理小数点后面的数,注意是末尾不能有 0,对应之前的数组进阶小数点的前几位 0 去掉即可
if(len-index==2 && a[len-1]=='0')
b[g]='0';//小数点之后仅有一个 0 要保留
else{
for(int i=index+1;i<len;i++){
if(a[i]=='0' && g==f+1);
else{
b[g]=a[i];
g++;
}
}
}
for(int i=0;i<=f;i++)
cout<<b[i];
for(int i=strlen(b)-1;i>f;i--)//注意,由于上面是正序保存原有效数据,所以要逆序输出!
cout<<b[i];
}
else if(flag==3){
f=0;
if(index==1 && a[0]=='0')
b[0]='0';//单独考虑分子为 0
else{
for(int i=index-1;i>=0;i--){
if(a[i]=='0' && f==0);
else{
b[f]=a[i];
f++;//分子倒序
}
}
}
b[f]='/';
g=f+1;
for(int i=len-1;i>index;i--){//分母不可能为一个 0,不予考虑,与浮点数的不同之处还在于新的分母前几位不为 0,也就是原数组的末尾 0 去掉
if(a[i]=='0' && g==f+1);
else{
b[g]=a[i];
g++;
}
}
for(int i=0;i<strlen(b);i++)
cout<<b[i];
}
else{
f=0;
b[0]='0';//为 0% 时发挥作用
for(int i=len-2;i>=0;i--){
if(a[i]=='0' && f==0);
else{
b[f]=a[i];
f++;
}
}
for(int i=0;i<strlen(b);i++)
cout<<b[i];
cout<<'%';
}
return 0;
}
下面是乱码问题:
输入
输出
0
0闌
0%
0闌%
5
5闌
我不是很明白为什么会这样。。。
但有一点可以大致确定,是 strlen( ) 函数的问题
哈哈哈,挺开心的,我找到了原因:原来组成数组 b 的过程中没有在末尾自动添加 ‘\0’,只能手动添加,才能得到正确的 strlen( )! 下面是“改进”的代码(变麻烦了。。):
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main(){
char a[30],b[30],c[30];//分别输入字符串数组和输出新的字符串数组
//新增数组 c 单独存储符号后面的有效数据
int flag=1,index=-1,len,f,g;
cin>>a;//直接输入即可,但是中间不能有空格,换行符,还好本题没有
len=strlen(a);// cstring 头文件中的计算字符串实际长度的函数,与预设的数组空间无关,数组空间函数用相同头文件下的 sizeof() 函数,以'\0'为结束标志
for(int i=0;i<len;i++){
// flag==1 代表整数(字符串)类型
if(a[i]=='.'){
flag=2;// flag 为 2 时表示浮点数
index=i;//记录小数点位置
break;//找到符号位就跳出循环
}
else if(a[i]=='/'){
flag=3;
index=i;
break;
}
else if(a[i]=='%'){
flag=4;
//不必记录百分号的位置了,显而易见
break;
}
else;//空语句
}
if(flag==1){//处理整型
f=0;
if(len==1 && a[0]=='0'){
b[0]='0';//单独考虑为 0 情况
b[1]='\0';//需要手动添加'\0'
}
else{
for(int i=len-1;i>=0;i--){
if(a[i]=='0' && f==0);//舍弃 0
else{
b[f]=a[i];//将有效的数据存入数组 b
f++;
}
}
b[f]='\0';
}
for(int i=0;i<strlen(b);i++)
cout<<b[i];
}
else if(flag==2){
f=0;
if(index==1 && a[0]=='0'){
b[0]='0';
b[1]='\0';//小数点之前只有一个 0 时
}
else{
for(int i=index-1;i>=0;i--){
if(a[i]=='0' && f==0);
else{
b[f]=a[i];
f++;//数组 b 存放有效的小数点之前的数
}
}
b[f]='\0';
}
g=0;//开始处理小数点后面的数,注意是末尾不能有 0,对应之前的数组进阶小数点的前几位 0 去掉即可,用数组 c 存储
if(len-index==2 && a[len-1]=='0'){
c[g]='0';//小数点之后仅有一个 0 要保留
c[g+1]='\0';
}
else{
for(int i=index+1;i<len;i++){
if(a[i]=='0' && g==0);
else{
c[g]=a[i];
g++;
}
}
c[g]='\0';
}
for(int i=0;i<strlen(b);i++)
cout<<b[i];
cout<<'.';//单独直接输出小数点,不放数组里面了
for(int i=strlen(c)-1;i>=0;i--)//注意,由于上面是正序保存原有效数据,所以要逆序输出!
cout<<c[i];
}
else if(flag==3){
f=0;
if(index==1 && a[0]=='0'){
b[0]='0';//单独考虑分子为 0
b[1]='\0';
}
else{
for(int i=index-1;i>=0;i--){
if(a[i]=='0' && f==0);
else{
b[f]=a[i];
f++;//分子倒序
}
}
b[f]='\0';
}
g=0;
for(int i=len-1;i>index;i--){//分母不可能为一个 0,不予考虑,与浮点数的不同之处还在于新的分母前几位不为 0,也就是原数组的末尾 0 去掉
if(a[i]=='0' && g==0);
else{
c[g]=a[i];
g++;
}
}
c[g]='\0';
for(int i=0;i<strlen(b);i++)
cout<<b[i];
cout<<'/';
for(int i=0;i<strlen(c);i++)
cout<<c[i];
}
else{
f=0;
if(len==2 && a[0]=='0'){
b[0]='0';
b[1]='\0';
}
else{
for(int i=len-2;i>=0;i--){
if(a[i]=='0' && f==0);
else{
b[f]=a[i];
f++;
}
}
b[f]='\0';
}
for(int i=0;i<strlen(b);i++)
cout<<b[i];
cout<<'%';
}
return 0;
}
过了,但是代码量太大了有木有?学习了如下简便的写法:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main(){
string s;//直接初始化为字符串类型
char p=' ';//存放符号
int len=0;
cin>>s;
for(int i=0;i<s.size();i++){
if(s[i]>='0' && s[i]<='9')
len++;//统计出现符号之前的数字个数
else{
p=s[i];
break;
}
}
int flag=len;//拷贝一份 len 记录符号位置
len--;
while(s[len]=='0' && len>0)
len--;//倒序寻找 0 ;直到不为 0 跳出循环,这时 len 的值恰好是要输出有效数据的起始位置(倒序输出)
for(int i=len;i>=0;i--)
cout<<s[i];
if(p==' ')
return 0;//整型的话就完成了,跳出主函数
else{
if(p=='%'){
cout<<p;
return 0;//百分数的话再输出一个百分号就结束啦
}
else
cout<<p;//下面考虑浮点数与分数后半部分
}
int flag0=s.size()-1;
//对于浮点数,初始数据后半部分可能有 0 ,输出的后半部分末尾不能有 0 ,除非只有 0 要保留一个:
while(s[flag+1]=='0' && flag<flag0-1)
flag++;//舍弃要输出的末尾的 0 ,除非只有一个 0
//对于分数,初始数据分母末尾可能有 0 ,输出的分母开头不能有 0 ,且分母不会只有一个 0:
while(s[flag0]=='0' && flag0>flag+1)
flag0--;
for(int i=flag0;i>flag;i--)
cout<<s[i];//倒序输出后半部分有效数据
return 0;
}
一个明智的人就是一个不会被表面现象所欺骗的人,他甚至预见到了事情将往哪一方向变化。——叔本华
希望自己解题时也能洞见本质。。。
标签:index,int,反转,len,else,--,P1553,&&,升级版 来源: https://blog.csdn.net/interestingddd/article/details/114735521