題目指路: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;
}
大佬解法傳送門。
本蒟蒻覺得我寫的肯定是解此題最麻煩的方法了,歡迎大佬指正。