PTA1002 寫出這個數 (20 分)
阿新 • • 發佈:2022-03-16
1002 寫出這個數 (20 分)
讀入一個正整數 n,計算其各位數字之和,用漢語拼音寫出和的每一位數字。
輸入格式:
每個測試輸入包含 1 個測試用例,即給出自然數 n 的值。這裡保證 n 小於 10100。
輸出格式:
在一行內輸出 n 的各位數字之和的每一位,拼音數字間有 1 空格,但一行中最後一個拼音數字後沒有空格。
輸入樣例:
1234567890987654321123456789
輸出樣例:
yi san wu
C演算法實現:
#include<stdio.h> int main(){ int sum=0,k=0,sum1,s[15]; char ch; //每次讀取一個數 ch = getchar(); while(ch!='\n'){ switch(ch){ case '1':sum=sum+1;break; case '2':sum=sum+2;break; case '3':sum=sum+3;break; case '4':sum=sum+4;break; case '5':sum=sum+5;break; case '6':sum=sum+6;break; case '7':sum=sum+7;break; case '8':sum=sum+8;break; case '9':sum=sum+9;break; case '0':sum=sum+0;break; } ch = getchar(); } //printf("%d",sum); sum1=sum; //判斷是幾位數 while(sum1){ sum1=sum1/10; k++; } for(int i=k-1;i>=0;i--){ s[i]=sum%10;//分別求每位數 sum=sum/10; } for(int i=0;i<k;i++){ switch(s[i]){ case 1:printf("yi");break; case 2:printf("er");break; case 3:printf("san");break; case 4:printf("si");break; case 5:printf("wu");break; case 6:printf("liu");break; case 7:printf("qi");break; case 8:printf("ba");break; case 9:printf("jiu");break; case 0:printf("ling");break; } if(i!=(k-1)) {printf(" ");} else{ printf("\n"); } } return 0; }
思想:由於輸入的數可達10的100次方,所以用陣列儲存不現實,因此可將數字作為字元輸入,用getchar方法迴圈獲取一個數,當獲取到的字元為回車(‘\n’)時停止,再用switch進行判斷,即可求出所有數之和,定義一個k來標記是幾位數,再用陣列儲存每一位上的數字,最後對應字串輸出
演算法二(一點點小改進,C++實現):
#include<bits/stdc++.h>//通用懶人寫法,包含所有的庫函式,由於本人還沒來得及系統學習stl,也一般不會 //涉及到高階的庫函式,所以就這麼寫了,建議還是系統學習stl using namespace std; int main(){ string n; cin>>n; int i=0,sum=0,sum1,k=0,s[10]; while(n[i]!='\0'){ sum=sum+(n[i]-'0'); i++; } //cout<<sum; sum1=sum; //判斷是幾位數 while(sum1){ sum1=sum1/10; k++; } for(int i=k-1;i>=0;i--){ s[i]=sum%10;//分別求每位數 sum=sum/10; } for(int i=0;i<k;i++){ switch(s[i]){ case 1:cout<<"yi";break; case 2:cout<<"er";break; case 3:cout<<"san";break; case 4:cout<<"si";break; case 5:cout<<"wu";break; case 6:cout<<"liu";break; case 7:cout<<"qi";break; case 8:cout<<"ba";break; case 9:cout<<"jiu";break; case 0:cout<<"ling";break; } if(i!=(k-1)) {cout<<" ";} else{ cout<<endl; } } return 0; }
思想:將要輸入的變數定義為一個字串,當輸入的字元為‘\0’,也就是回車時,結束輸入(‘\0’獲取不到),所得的字串可以直接作為陣列使用,通過下標獲取元素,當所得字元為數字時,可以用s[i]-'0'將數字字元轉化為int型別的數字進行四則運算。
演算法三(貼一個大佬的簡潔程式碼,供參考學習)
#include <iostream> using namespace std; int main() { int sum = 0; char ch, s[4]; //ch作為臨時變數儲存輸入的每一個字元,s儲存sum的每一個數字 ,因為題目小於1000 char b[10][5] = { "ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu" }; while ((ch = getchar()) != '\n') //如果一直輸入字元,不按回車的話 sum += (ch - '0'); sprintf_s(s, "%d", sum); // sprintf(char *buffer, const char *format,[ argument])將任意型別資料按某種格式轉換成字串 for (int i = 0; s[i] != 0; i++) { if (i > 0) //消除第一個空格 printf(" "); printf("%s", b[s[i] - '0']); } return 0;//上文sprintf中s為s[4]陣列名,將sum的值存放在s中 }
幾點思考:
-
可以把相應的格式字串儲存到字元陣列中,char b【10】【5】中的5代表最大長度(10行5列)
-
本題的精華所在,之前的做法都是想著判斷所得到的數是幾位數,再如何把每位上的數字存下來,所以用了for迴圈判斷,而c++的庫函式sprintf_s()提供了這個功能,不過有以下注意點(感謝評論大佬!!!):
- 帶“_s”字尾的函式一般是為了讓原版函式更安全,編譯器(如VS)提供了sprintf_s()的話,不會出現編譯錯誤,而PAT應該是沒有提供的,所以需要去掉“_s”字尾。
- 但是在vs裡反而是sprintf不讓用,一定要你用sprintf_s
-
可用%s直接輸出字元陣列中的所有字元