数据结构与算法刷题笔记(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.输入输出要求

数据结构与算法刷题笔记(No.002)——PAT1002写出这个数(C/Java语言实现)_第1张图片

3.题目解析

这道题有一个初学者容易忽视的坑,就是本题的输入数据的值有可能会非常大,最大可能到10^100,这样的数是任何整数类型都存不下的,因此需要用字符串去存储一个整数,由此带来的问题是处理过程中会有一些小麻烦,要进行ASCII码的转换。

3.1 输入数据

输入一个很大很大的整数,大到任何整数类型都存不下(会溢出),因此程序要考虑把数字当做字符串去处理。

3.2 算法处理

首先,要能读取并准确存储一个字符串,于是写下这样的C代码:

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

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(PAT刷题笔记)