非常簡單的一題了,但還是交了兩三次,原因:對數組的理解不足;對數字和字元之間的轉換不夠敏感。這將在下文中細說。 Given a non-negative integer N, your task is to compute the sum of all the digits of N, and ou ...
非常簡單的一題了,但還是交了兩三次,原因:對數組的理解不足;對數字和字元之間的轉換不夠敏感。這將在下文中細說。
Given a non-negative integer N, your task is to compute the sum of all the digits of N, and output every digit of the sum in English.
Input Specification:
Each input file contains one test case. Each case occupies one line which contains an N (≤10100).
Output Specification:
For each test case, output in one line the digits of the sum in English words. There must be one space between two consecutive words, but no extra space at the end of a line.
Sample Input:
12345
Sample Output:
one five
題目分析
輸入一串數字,然後用英文表達所有數字相加和的每一位數字。
輸入:10100以內的數字
輸出:和的每位數字英文表達(eg:sum=256,output=two five six)
首先很明顯代碼是不會翻譯你的結果的,所有用一個數組來存儲表示每位數字的英文,其次,10100的數字不需要精準表示,因為這裡也就100個數字,不是10100個數字,開始我在這卡了半天,想著數字太大要精準存儲,特地翻了之前寫的c語言-大數階乘 - 1001010 - 博客園 (cnblogs.com)一文,後面發現不大行的通,審視一遍後發現了問題,最後輸出,要怎麼拆開數字和也是個問題。
個人想法
首先,還是從變數入手
1 #define MAX 100 2 int N,m;//輸入N,用於統計N的位數m 3 char lan[10][10] = { "zero","one","two","three","four","five","six","seven","eight","nine" }; 4 int sum,a[MAX];//計算和sum,數組a用來記錄拆開的sum 5 char n[MAX];
這裡開始是想N用來輸入數據,後面發現迴圈過程中因為不知道它的位數,所以往往遍歷要很多【補:而且N作為int變數放不了100位,double型的時候可以,但sum作為int不能讓N強轉,都作為double時就會很麻煩】,所以在錯了一次後採取了 char n[MAX]; 的寫法,這樣有很多的妙處:
- 可以利用字元串來進行自動分割,即在輸入時不賦值在地址上(n的每位地址),scanf("%s", &n[i]); ❌ scanf("%s", &n);❌ scanf("%s", n);✔ c語言因為只接受字元,不支持string,寫成這樣就會自動把一串數字字元串分成單獨的數字字元並賦值在每個空間單位上。
- 迴圈遍歷時,不需要知道有幾位,因為每個字元是被附在每個單位空間上的,所以這個數組遍歷到空,即'\0'就可以停止。
- 由於得到的是字元的地址(數字自生的ACII值),所以在計算sum時,不用強轉,而是減去0的ACII值,這個差不僅是地址差也非常融洽的是數字之間的差。
到這裡其實已經沒有什麼疑惑的點了,下麵直接上完整代碼。
1 #include<stdio.h> 2 3 #define MAX 150 4 int N,m; 5 char n[MAX]; 6 char lan[10][10] = { "zero","one","two","three","four","five","six","seven","eight","nine" }; 7 int sum,a[MAX]; 8 int main() { 9 scanf("%s", n); 10 for (int i = 0; n[i] != '\0'; i++) { 11 sum += n[i] - '0'; 12 } 13 if (sum == 0){printf("zero");return 0;}//如果和等於0 ,那麼直接輸出“zero”就行。註意,這裡必須return終止,因為數組a[-1]也是0 14 for (int i = 0; sum; i++) { 15 a[i] = sum % 10; 16 sum /= 10; 17 m += 1;//m記錄sum的位數,但註意數組在使用時要減1,因為超範圍了 18 }//sum最後等於0時即完成所有位數的記錄,終止迴圈(非常巧妙) 19 20 printf("%s", lan[a[m - 1]]); 21 for(int i=m-2;i>=0;i--) 22 printf(" %s", lan[a[i]]);//老一套輸出格式,每一位的數字對於英語組記錄的每一位上的英文 23 24 return 0; 25 }
總結
- 數組的利用,例如本文對英語的存儲採用了二維數組,由於是char型,每單位只存放一個字元,所以lan[10][10]有10行10列,每列存放一個字元,一行存放10個字元。如果列數不足或是剛好,就會因為沒有讀到 '\0' 而出現連續輸出,如下。每列只有5個單位,故原本“seven”就該停止卻因為沒有 '\0' 而讀取到下一行“eight”一直到“nine”才停下。同樣還有上文提到的數組地址。
- 字元與數字的轉換。
- 停止條件的巧妙使用,如這裡for迴圈採用sum=0停止的條件,是我個人之前沒看過的。