BLOG-1_JavaHomework_Summary

PTA大作业_阶段性总结

前言

虽说上学期为了助眠看了一点 Java 但是散而不精,看而不敲,所以这学期正式学 Java 并没有想象中那么容易…

javaC/C++区别的直观感受:最直观感受是运行速度, Java 的运行速度比 C/C++ 要慢许多

前三次PTA题目集的小总结

总体来看,前两次的题目集偏基础一点,会使用简单的循环结构、条件判断、格式化输出和字符串操作便可轻松满分,题量难度都不算大,但是第三次的题目集便立马感受到了压力;

第三次的题目集不仅提高了对Java基础的要求,还要求从面向过程的思路转化到面向对象的思维上,在做题前看题便可以注意到,若不使用类和对象便会大大增加代码量且不易于维护,另外,第三次题目集还对输入格式的把控提出了苛刻的要求,还要求将数学知识运用到程序中(数学是硬伤啊),并时刻注意变量的存储类型和输出格式。最重要的是在动手写之前构思:如何分配对象的方法,如何联系对象与对象之间…..

设计与分析

题目集2_7-2

源码的生成报表

BLOG-1_JavaHomework_Summary
代码类图
BLOG-1_JavaHomework_Summary
分析 : 一眼丁真:纯纯的面向过程,代码简洁,充斥着 if-else ,可读性不是很高

题目集3_7-1

源码的生成报表

BLOG-1_JavaHomework_Summary
代码类图
BLOG-1_JavaHomework_Summary
分析 : 相比之前,有了更多的方法,代码量也随之增加

题目集3_7-2

源码的生成报表

BLOG-1_JavaHomework_Summary
代码类图
BLOG-1_JavaHomework_Summary
分析 : 使用了更多的类,并以对象进行数据计算代码清晰了很多

题目集3_7-3

源码的生成报表

BLOG-1_JavaHomework_Summary
代码类图
BLOG-1_JavaHomework_Summary
分析 : 使用了更多的类,并以对象进行数据计算代码清晰了很多

采坑心得

这波?这波是 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> &#x4F1A;&#x4F7F;<code>str.charAt(i)</code>&#x8D8A;&#x754C;<!--=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++中, 0false,非 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
////////////////////////////////////////////////////

还有好几段这样类似的代码,因为写的过程中为了缩短工期而写出的 &#x5C4E;&#x5C71;
明显看到,可以对其进行优化,大大提升可维护性,并使代码更简洁
改进

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/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 图解设计模式:身份认证场景的应用

    文章首发在公众号(龙台的技术笔记),之后同步到博客园和个人网站:xiaomage.info 今天和大家聊一聊,如何合理的将多种设计模式放到同一个业务场景中 业务背景 最近接到一个认…

    Java 2023年6月14日
    0105
  • Java编译到执行的过程

    Java编译到执行的过程 执行过程: 编译→加载→解释→执行 运行过程 .Java→.class→装载到JVM→.class→可执行指令→调用系统硬件执行最终指令 详细过程 编译过…

    Java 2023年6月8日
    0163
  • eclipse安装Spring插件时报错

    eclipse安装Spring插件时报错: cannot perform operation.Computing alertnate solutions,may take a wh…

    Java 2023年5月29日
    088
  • 大三上 期中考试

    湛江师范学院 2014 - 2015 学年度第 1 学期 期中试卷 科目:LINUX 平台及应用 C 编程 shell编程 100 蔡广基 评卷人 蔡广基 一、操作题。添加一个 1…

    Java 2023年6月13日
    077
  • Ubuntu 20.04 查看内存信息

    输入命令 dmidecode -t memory 输出如下: dmidecode 3.2 Getting SMBIOS data from sysfs. SMBIOS 2.8 pr…

    Java 2023年6月7日
    093
  • Final

    final 基本介绍: final可以修饰类、属性、方法和局部变量 下面情况下可能会用到final 当不希望类被继承时,可以用final修饰; 当不希望父类的某个方法被子类覆盖/重…

    Java 2023年6月5日
    077
  • 如何自动化你的Excel导入导出(Java)?

    如遇图片无法显示,请前往掘金查看原文 GitHub | 中文 | English | 博客 为什么使用AutoExcel? Excel导入导出在软件开发中非常常见,只要你接触过开发…

    Java 2023年5月29日
    093
  • Mysql重复数据查询置为空

    前两天产品有个需求,相同的商品因为价格不同而分开展示,但是明细还是算一条明细,具体区分展示出商品的价格和数量信息,其他重复的商品信息要置空。 需求并不难,用程序代码循环处理就可以了…

    Java 2023年6月5日
    086
  • 二叉搜索树和平衡二叉树

    写在前面 前面讲了树的基本概念,这篇文章主要讲常见的树的基本操作,如查找,新增,删除等。其中通过动图的方式使得更加容易理解。 二叉查找树 二叉查找树(BST,Binary Sort…

    Java 2023年6月5日
    073
  • Spring 集成 Swagger

    Swagger 是一个规范且完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务 Swagger 的目标是对 REST API 定义一个标准且和语言无关的…

    Java 2023年5月30日
    083
  • Redis做Mybatis的二级缓存

    基于spring boot项目的前提下,使用redis数据库做mybatis的二级缓存。 Redis做mybatis的二级缓存 作用提升速度,保证多台服务器访问同一数据库时不会崩注…

    Java 2023年6月14日
    070
  • 郭洁姐姐生日快乐~

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年6月5日
    073
  • Nginx服务加到systemctl

    当我们编译安装nginx服务后,可以用手执行启动脚本也可以作为服务的形式运行。 添加启动文件:vim /usr/lib/systemd/system/nginx.service c…

    Java 2023年5月30日
    073
  • SpringSecurity中的CSRF解读

    从刚开始学习SpringSecurity时,在配置类中一直存在这样一行代码:http.csrfo.disable() 如果没有这行代码导致用户无法被认证。这行代码的含义是:关闭 c…

    Java 2023年6月5日
    073
  • CS144lab笔记

    下面看代码: lab0 webget.cc 点击查看代码 webget.cc byte_stream.hh 点击查看代码 // ccm #ifndef SPONGE_LIBSPON…

    Java 2023年6月5日
    081
  • [二分法]求解递增序列中与x最接近元素问题

    在一个非降序列序列中与给定值 x 最接近的元素 第一行包含一个整数 n,为非降序列长度 (1 Original: https://www.cnblogs.com/fordsonli…

    Java 2023年6月5日
    0101
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球