數據結構與算法刷題筆記(No.002)——PAT1002寫出這個數(C/Java語言實現)

博主的數據結構刷題筆記,自己的練習記錄,供大家參考,文中所列代碼均經反覆調試或OJ系統判定通過,如仍有疏漏歡迎大家留言指正,文中算法優化不足的地方歡迎大家留言交流,感謝。

目錄

1.題目

2.輸入輸出要求

3.題目解析

3.1 輸入數據

3.2 算法處理

3.3 輸出數據

3.4 涉及到的主要知識點

3.5 Java語言實現源代碼

3.6 C語言實現源代碼

4.總結


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大法好。

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章