1. 程式人生 > 其它 >PTA1002 寫出這個數 (20 分)

PTA1002 寫出這個數 (20 分)

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中 
}



幾點思考:

  1. 可以把相應的格式字串儲存到字元陣列中,char b【10】【5】中的5代表最大長度(10行5列)

  2. 本題的精華所在,之前的做法都是想著判斷所得到的數是幾位數,再如何把每位上的數字存下來,所以用了for迴圈判斷,而c++的庫函式sprintf_s()提供了這個功能,不過有以下注意點(感謝評論大佬!!!):

    • 帶“_s”字尾的函式一般是為了讓原版函式更安全,編譯器(如VS)提供了sprintf_s()的話,不會出現編譯錯誤,而PAT應該是沒有提供的,所以需要去掉“_s”字尾。
    • 但是在vs裡反而是sprintf不讓用,一定要你用sprintf_s
  3. 可用%s直接輸出字元陣列中的所有字元