PTA大作业_阶段性总结
前言
虽说上学期为了助眠看了一点 Java 但是散而不精,看而不敲,所以这学期正式学 Java 并没有想象中那么容易…
对 java
和 C/C++
区别的直观感受:最直观感受是运行速度, Java
的运行速度比 C/C++
要慢许多
前三次PTA题目集的小总结
总体来看,前两次的题目集偏基础一点,会使用简单的循环结构、条件判断、格式化输出和字符串操作便可轻松满分,题量难度都不算大,但是第三次的题目集便立马感受到了压力;
第三次的题目集不仅提高了对Java基础的要求,还要求从面向过程的思路转化到面向对象的思维上,在做题前看题便可以注意到,若不使用类和对象便会大大增加代码量且不易于维护,另外,第三次题目集还对输入格式的把控提出了苛刻的要求,还要求将数学知识运用到程序中(数学是硬伤啊),并时刻注意变量的存储类型和输出格式。最重要的是在动手写之前构思:如何分配对象的方法,如何联系对象与对象之间…..
设计与分析
题目集2_7-2
源码的生成报表
代码类图
分析 : 一眼丁真:纯纯的面向过程,代码简洁,充斥着if-else
,可读性不是很高
题目集3_7-1
源码的生成报表
代码类图
分析 : 相比之前,有了更多的方法,代码量也随之增加
题目集3_7-2
源码的生成报表
代码类图
分析 : 使用了更多的类,并以对象进行数据计算代码清晰了很多
题目集3_7-3
源码的生成报表
代码类图
分析 : 使用了更多的类,并以对象进行数据计算代码清晰了很多
采坑心得
这波?这波是
Java
搞偷袭,是我大意了啊,没有闪。但没关系….(%^&%)!(%)”]$]!]@.~\·.!~@^[\//*’;]/=/[/[\&/]]@=/]/!-[/-‘%/¥
1)数据存储与输出
浮点数保留位数问题
需求:若输出的数据小数点后超过6位,只保留小数点后6位,多余部分采用四舍五入规则进到最低位。小数点后若不足6位,按原始位数显示。
踩坑笔记
踩坑思路:
printf
会自动四舍五入,所以直接使用printf格式化输出
//假定要保留六位小数
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
float a = in.nextFloat(), b = in.nextFloat();
System.out.printf("a/b: %.6f a+b: %.6f", a / b, a + b);
}
发现问题:
a/b
是确确实实按6位保留并四舍五入了,但是a+b
本应输出5.0
却也多了几个0
//输入
2 3
//输出
a/b: 0.666667 a+b: 5.000000
影响:PTA答案错误!
解决方法
问题分析:
%f
会一视同仁格式化所有浮点数,所以只要让其该根据数据位数来选择是否要格式化为6位即可
正确写法:
//假定要保留六位小数
public static void formatPrint(float n) {
final int esp = (int)1e6;
if(((n*esp)%10)!=0) //小数点后第六位数不为0
System.out.printf("%.6f",n); //格式化输出
else
System.out.print(n);
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
float a = in.nextFloat(), b = in.nextFloat();
System.out.print("a/b: ");
formatPrint(a/b);
System.out.print(" a+b: ");
formatPrint(a+b);
}
问题解决:
//输入
2 3
//输出
a/b: 0.666667 a+b: 5.0
反思:若第6位恰好是0呢?是否可以用 String.format()
格式化输出?使用 DecimalFormat
格式化?使用 BigDecimal.setScale
格式化?
2)其他
忽略if( )中的判断顺序
需求:将字符串根据逗号
,
或者空格 来分割成若干部分字符串,并转化为实数
踩坑笔记
踩坑原因:将循环边界判断放在了
charAt()
之后
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();
String[] nums = new String[10];
int idx=0;
for(int i=0,j=0;i
发现问题:
数组越界?
//输入
12,23 34.1,45
//报错
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 13
at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:47)
at java.base/java.lang.String.charAt(String.java:693)
at Main.main(Main.java:24)
影响:程序运行异常终止
解决方法
问题分析:根据调试发现,
if()
括号中的判断遵循从左到右顺序,由于i == str.length()
放在最后,所以先判断str.charAt(i)
但是循环的条件是i<=str.length()< code> 会使<code>str.charAt(i)</code>越界<!--=str.length()<-->
正确写法:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in .nextLine();
String[] nums = new String[10];
int idx=0;
for(int i=0,j=0;i
问题解决:
//输入
12,23 34.1,45
//输出
12 23 34.1 45
反思:挺完美了吧(指按格式正常输入的话)
C/C++带来的坏习惯
需求:简化题目中多组数据的输入,
踩坑笔记
踩坑原因:不知
Java
的类型一定要完全匹配
//输入T为组数,每组输入一个数并将其输出
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int T = in.nextInt();
int t;
while(T--){
t = in.nextInt();
System.out.println(t);
}
}
影响:直接error
解决方法
问题分析:C/C++中,
0
是false
,非0
的数便是true
,但Java
不这么认为,所以只要将int
转化为boolean
就好
正确写法:
//输入T为组数,每组输入一个数并将其输出
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int T = in.nextInt();
int t;
while(T-->0){
t = in.nextInt();
System.out.println(t);
}
}
问题解决:
3 //输入
111 //输入
111
222 //输入
222
333 //输入
333
//进程已结束,退出代码0
反思:若每组数据要输入String,怎么使其不读入组数后的回车?
改进建议
由于之前的小题不需要有整体的构思,导致第三次作业潦草起手,使得后期维护难上加难,所以动手之前应该考虑工程大小、各部分的责任范围、
引言:贯穿始终的一条原则就是”想好再做”。如果实在”想不好”,那就”做一点”,出了问题再”好好想”。在实践中,”做一点”的度很难把握,常常是开了闸就一泻千里。怎么判断这个度呢?我觉得说到底是你对程序的掌控感,要保持程序始终在你的控制之下。比如如果一个函数超过了50行,就是一个危险的信号。
————————————————原文链接:https://blog.csdn.net/RiderOnStorm/article/details/594775
代码复制问题
在第三次作业最开始的版本中,有很严重的代码复制情况:
//比如这段 作用是将字符串从第二位下标开始,根据空格和逗号分割为若干部分字符串,并将其转化为实数存于数组
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();
int choice = str.charAt(0) - '0';
str = str.substring(2); //跳过开始的两个字符
String[][] nums = new String[4][];
String[] location = str.split(" "); //按空格分为若干个字符串数组
for (int i = 0; i < 4; i++)
nums[i] = location[i].split(","); //按逗号分为若干个字符串数组
float[] fls = new float[8];
fls[0] = Float.parseFloat(nums[0][0]);
fls[1] = Float.parseFloat(nums[0][1]);
fls[2] = Float.parseFloat(nums[1][0]);
fls[3] = Float.parseFloat(nums[1][1]);
fls[4] = Float.parseFloat(nums[2][0]);
fls[5] = Float.parseFloat(nums[2][1]);
fls[6] = Float.parseFloat(nums[3][0]);
fls[7] = Float.parseFloat(nums[3][1]);
for (float j : fls) System.out.println(j); //仅供测试功能
}
////////////////////////////////////////////////////
//输入
1:1,2 3,4 5,6 7,8
//输出
1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
////////////////////////////////////////////////////
其他地方或许只是数量不同
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();
int choice = str.charAt(0) - '0';
str = str.substring(2);
String[][] nums = new String[4][];
String[] location = str.split(" ");
for (int i = 0; i < 3; i++)
nums[i] = location[i].split(",");
float[] fls = new float[6];
fls[0] = Float.parseFloat(nums[0][0]);
fls[1] = Float.parseFloat(nums[0][1]);
fls[2] = Float.parseFloat(nums[1][0]);
fls[3] = Float.parseFloat(nums[1][1]);
fls[4] = Float.parseFloat(nums[2][0]);
fls[5] = Float.parseFloat(nums[2][1]);
for (float j : fls) System.out.println(j);
}
////////////////////////////////////////////////////
//输入
1:1,2 3,4 5,6
//输出
1.0
2.0
3.0
4.0
5.0
6.0
////////////////////////////////////////////////////
还有好几段这样类似的代码,因为写的过程中为了缩短工期而写出的 屎山
明显看到,可以对其进行优化,大大提升可维护性,并使代码更简洁
改进
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();
int choice = str.charAt(0) - '0';
str = str.substring(2);
String[][] nums = new String[4][];
int len = 4;
float[] fls = transform(len, str, nums); //传入数据
for (float j : fls) System.out.println(j);
}
public static float[] transform(int size, String str, String[][] num) { //将字符串处理为数组
float[] res = new float[2 * size];
String[] location = str.split(" ");
for (int i = 0; i < size; i++)
num[i] = location[i].split(",");
for (int i = 0, j = 0, k = 0; i < 2 * size; i++, k++, j += k / 2, k %= 2) {
res[i] = Float.parseFloat(num[j][k]);
}
return res;
}
////////////////////////////////////////////////////
//输入
1:1,2 3,4 5,6 7,8
//输出
1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
////////////////////////////////////////////////////
改进2.0
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();
int choice = str.charAt(0) - '0';
str = str.substring(2);
int pointCnt = 4;
float[] fls = transform(pointCnt, str); //传入数据
for (float j : fls) System.out.println(j);
}
public static float[] transform(int size, String str) { //将字符串处理为数组
String[][] nums = new String[2 * size][];
float[] res = new float[2 * size];
String[] location = str.split(" ");
for (int i = 0; i < size; i++)
nums[i] = location[i].split(",");
for (int i = 0, k = 0; i < 2 * size; i++, k++, k %= 2) { //并不需要 j
res[i] = Float.parseFloat(nums[i / 2][k]);
}
return res;
}
////////////////////////////////////////////////////
//输入
1:1,2 3,4 5,6 7,8
//输出
1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
////////////////////////////////////////////////////
除数为0不一定报错问题
之前遇到过
int
的0作为除数会报错的情况,便没有再深究
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
a=in.nextInt();b=in.nextInt();
c=in.nextInt();d=in.nextInt();
System.out.println(getSlope());
}
public static int getSlope() {
return (a - b) / (c - d);
}
结果异常
//输入
2 2 3 3
//输出
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.getSlope(Main.java:14)
at Main.main(Main.java:10)
//进程已结束,退出代码1
但是如果是 double
类型,结果就变得有趣了起来
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
a=in.nextInt();b=in.nextInt();
c=in.nextInt();d=in.nextInt();
System.out.println(getSlope());
}
public static double getSlope() {
return (a - b) / (c - d);
}
Not a Number
//输入
2 2 3 3
//输出
NaN
//进程已结束,退出代码0
正无穷
//输入
3 2 2 2
//输出
Infinity
//进程已结束,退出代码0
负无穷
//输入
2 3 3 3
//输出
-Infinity
//进程已结束,退出代码0
总结
通过该阶段的学习,学到了程序基本的整体构思思路、类与类的分工。但对于输入数据格式问题,仍存在考虑不全不周的问题,需要在今后的学习中着重注意。
对作业的感觉:挺有挑战性的,值得一做!
对今后学习方法的建议:不要只看不敲,看懂不等于学会,当然,若能用最精简的语言点通不懂的人,那便证明你真正学到点东西了。Original: https://www.cnblogs.com/Pseach/p/16124608.html
Author: Pseach
Title: BLOG-1_JavaHomework_Summary
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/571532/
转载文章受原作者版权保护。转载请注明原作者出处!