博主的數據結構刷題筆記,自己的練習記錄,供大家參考,文中所列代碼均經反覆調試或OJ系統判定通過,如仍有疏漏歡迎大家留言指正,文中算法優化不足的地方歡迎大家留言交流,感謝。
目錄
1.題目
寫出這個數 (20 分)
讀入一個正整數 n,計算其各位數字之和,用漢語拼音寫出和的每一位數字。
2.輸入輸出要求
3.題目解析
這道題有一個初學者容易忽視的坑,就是本題的輸入數據的值有可能會非常大,最大可能到10^100,這樣的數是任何整數類型都存不下的,因此需要用字符串去存儲一個整數,由此帶來的問題是處理過程中會有一些小麻煩,要進行ASCII碼的轉換。
3.1 輸入數據
輸入一個很大很大的整數,大到任何整數類型都存不下(會溢出),因此程序要考慮把數字當做字符串去處理。
3.2 算法處理
首先,要能讀取並準確存儲一個字符串,於是寫下這樣的C代碼:
#include <stdio.h>
#define N 50 //假設最大的數的位數最大到49位(最後一位是字符串的結束符\0)
int main(void)
{
char data[N];
int i = 0;
scanf("%s",data);
printf("data: %s",data);
return 0;
}
測試了一下沒有問題,上面的代碼沒什麼好解釋的,就是最基本的變量、輸入輸出函數的簡單應用。
下面開始寫一個循環,遍歷並處理這個字符串中的每一個字符,遍歷過程要求出這個數字的和是多少,因此需要定義一個變量sum用作求和。C代碼如下:
#include <stdio.h>
#define N 50 //假設最大的數的位數最大到49位(最後一位是字符串的結束符\0)
int main(void)
{
char data[N];
int sum = 0;
int i = 0;
scanf("%s",data);
while(data[i]!='\0'){ //遍歷整個字符串
sum+=data[i]-'0'; //對每一個字符進行轉換,使每個字符變成所對應的數字
i++;
}
printf("sum = %d\n",sum);
printf("data: %s",data);
return 0;
}
比上面的代碼多了一個while循環,循環條件是隻要沒有遍歷到字符串的末尾就繼續遍歷。處理過程就是ASCII碼轉換成對應的數字並加到sum上。最後循環結束後輸出了原數據和各個位求和的結果。自己進行了簡單點的測試,沒問題。
上面的程序和最終結果已經很靠近了,就差最後一步用漢語拼音輸出一下結果了。
下面最後一個要解決的問題是,如何取得這個求和結果sum的各個位是多少,我的思路是首先將sum倒序存儲在一個數組裏,即如果sum爲12300,倒序存儲後變成00321(注意這裏不能用一個整數類型去存,不然前面的0都沒有了),然後挨個輸出數組中的數字對應的字符串就好了,注意每個字符串之間要多輸出一個空格,最後一個數字的後面沒有空格。
3.3 輸出數據
輸出數據是一組字符串,即用漢語拼音表示每個數字。
3.4 涉及到的主要知識點
1.字符串的讀取和輸出,字符串的基本操作。
2.ASCII碼的知識,可以參考百度百科:https://baike.baidu.com/item/ASCII/309296?fr=aladdin
3.5 Java語言實現源代碼
用java語言實現該題目,可以不用字符串存輸入數據了,直接用BigInteger更方便,同樣拼音數組用String類型比C語言的二維數組更方便。除此之外的算法處理部分都是一樣的。
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
BigInteger num = sc.nextBigInteger();//num爲讀取到的輸入數據
sc.close();
char[] data = num.toString().toCharArray();//直接將數字轉爲字符串,便於迭代
int sum = 0;
int[] sum_array= new int[50];
String numdata[] = { "ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu" };
int i = 0;
for (int j = 0; j < data.length; j++) {
sum += data[i] - '0'; // 對每一個字符進行轉換,使每個字符變成所對應的數字
i++;
}
i = 0;
//倒序保存求和值sum
while (sum != 0) {
sum_array[i] = sum % 10;
sum /= 10;
i++;
}
//計算結果輸出部分
System.out.print(numdata[sum_array[i-1]]);
for (int j = i - 2; j >= 0; j--) {
System.out.print(" "+numdata[sum_array[j]]);
}
}
}
上面代碼通過了PAT OJ系統的測評。
3.6 C語言實現源代碼
這段C語言代碼算法思路和上面java代碼一毛一樣,我在本地windows測試了很多組數據都沒問題,但是反覆修改了半天,提交上去一個都通過不了,貌似是我用的編譯器(DEV-C++)和PAT系統上的GCC編譯器有較大的差別。果然是C語言有很多方言,跨平臺性不好。
#include<stdio.h>
#include<string.h>
int main(void)
{
char data[100];
int sum = 0;
int i = 0,j;
char sum_array[20];
char numdata[][10]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
gets(data);
while(data[i]!='\0'){ //遍歷整個字符串
sum+=data[i]-'0'; //對每一個字符進行轉換,使每個字符變成所對應的數字
i++;
}
i = 0;
while(sum!=0){
sum_array[i] = sum%10;
sum/=10;
i++;
} //反序存儲
for(j=i-1;j>=0;j--){
printf("%s",numdata[sum_array[j]]);
printf(" ");
}
printf("\b");
return 0;
}
4.總結
這道題的一個坑就是對輸入數據的處理不能用整數類型去處理,而要用字符串類型。其餘之處都是字符串的常規操作了。
疑問:還沒搞清楚到底C語言代碼有何問題,通過不了OJ系統的測試。留在以後慢慢解決。Java大法好。