用户工具

站点工具


zh:courses:java2026:ch03

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
zh:courses:java2026:ch03 [2026/03/09 21:22]
pzczxs [课件]
zh:courses:java2026:ch03 [2026/03/30 19:18] (当前版本)
pzczxs [上机作业]
行 334: 行 334:
 ===== 上机作业 ===== ===== 上机作业 =====
   * 定义一个Date类,兼顾大月、小月和闰年2月等日期的计算,须包括方法tomorrow()和daysInMonth()。   * 定义一个Date类,兼顾大月、小月和闰年2月等日期的计算,须包括方法tomorrow()和daysInMonth()。
 +【参考答案】
 +<file java Date.java>​
 +package cn.edu.bjut.chapter3;​
 +
 +public class Date {
 + private int year, month, day; 
 +
 + public Date(int year, int month, int day) {
 + this.year = year; 
 + this.month = month; ​
 + this.day = day; 
 + }
 +
 + public int getYear() {
 + return year;
 + }
 +
 + public void setYear(int year) {
 + this.year = year;
 + }
 +
 + public int getMonth() {
 + return month;
 + }
 +
 + public void setMonth(int month) {
 + this.month = month;
 + }
 +
 + public int getDay() {
 + return day;
 + }
 +
 + public void setDay(int day) {
 + this.day = day;
 + }
 +
 + @Override
 + public String toString() {
 + return year + "​-"​ + month + "​-"​ + day;
 + }
 +
 + public int daysInMonth() {
 + switch (month) {
 + case 1: 
 + case 3: 
 + case 5: 
 + case 7: 
 + case 8:
 + case 10: 
 + case 12: 
 + return 31; //大月
 + case 4: 
 + case 6: 
 + case 9: 
 + case 11: 
 + return 30; //小月
 + default: // 2月
 + if (((year % 100 != 0) && (year % 4 == 0)) 
 + || (year % 400 == 0)) {
 + return 29; 
 +
 +
 + return 28; 
 + }
 + }
 +
 + public Date tomorrow() {
 + int tomorrowYear = year, tomorrowMonth = month, tomorrowDay = day; 
 +
 + if (day == daysInMonth()) {
 + tomorrowDay = 1; 
 + tomorrowMonth++; ​
 +
 + if (month == 12) {
 + tomorrowMonth = 1; 
 + tomorrowYear++; ​
 + }
 + } else {
 + tomorrowDay++; ​
 + }
 +
 + return (new Date(tomorrowYear,​ tomorrowMonth,​ tomorrowDay)); ​
 + }
 +
 + public static void main(String[] args) {
 + Date date = new Date(2017, 9, 30); 
 + System.out.println("​The number of days: " + date.daysInMonth());​
 + System.out.println(date + "​\n"​ + date.tomorrow());​
 +
 + Date date2 = new Date(2016, 2, 28); 
 + System.out.println("​The number of days: " + date2.daysInMonth());​
 + System.out.println(date2 + "​\n"​ + date2.tomorrow());​
 + }
 +}
 +</​file>​
   * 国际专利分类号(IPC)的前15位由section(部),class(大类),subclass(小类),main group(大组)和sub group(小组)五部分组成,每位的要求如下表所示,具体例子如:“G06F ​  ​17/​30”和“H01M ​  ​10/​587”,定义一个Ipc类,通过toString()函数将这五部分拼接成IPC的实际表现形式;   * 国际专利分类号(IPC)的前15位由section(部),class(大类),subclass(小类),main group(大组)和sub group(小组)五部分组成,每位的要求如下表所示,具体例子如:“G06F ​  ​17/​30”和“H01M ​  ​10/​587”,定义一个Ipc类,通过toString()函数将这五部分拼接成IPC的实际表现形式;
  
行 343: 行 439:
 | 9      | 分割符 ​             | /          | | 9      | 分割符 ​             | /          |
 | 10-14  | subgroup(左对齐) ​   | 0...99999 ​ | | 10-14  | subgroup(左对齐) ​   | 0...99999 ​ |
 +
 +【参考答案】
 +<file java Ipc.java>​
 +package cn.edu.bjut.chapter3;​
 +
 +public class Ipc {
 + private char section; ​
 + private int mainClass; ​
 + private char subclass; ​
 + private int mainGroup; ​
 + private int subgroup; ​
 +
 + private final static char SEPARATOR = '/'; ​
 +
 + public Ipc(char section, int mainClass, char subclass, int mainGroup, int subgroup) {
 + this.section = section; ​
 + this.mainClass = mainClass; ​
 + this.subclass = subclass; ​
 + this.mainGroup = mainGroup; ​
 + this.subgroup = subgroup; ​
 + }
 +
 + public char getSection() {
 + return section;
 + }
 +
 + public void setSection(char section) {
 + this.section = section;
 + }
 +
 + public int getMainClass() {
 + return mainClass;
 + }
 +
 + public void setMainClass(int mainClass) {
 + this.mainClass = mainClass;
 + }
 +
 + public char getSubclass() {
 + return subclass;
 + }
 +
 + public void setSubclass(char subclass) {
 + this.subclass = subclass;
 + }
 +
 + public int getMainGroup() {
 + return mainGroup;
 + }
 +
 + public void setMainGroup(int mainGroup) {
 + this.mainGroup = mainGroup;
 + }
 +
 + public int getSubgroup() {
 + return subgroup;
 + }
 +
 + public void setSubgroup(int subgroup) {
 + this.subgroup = subgroup;
 + }
 +
 + @Override
 + public String toString() {
 + StringBuilder sb = new StringBuilder(); ​
 +
 + sb.append(section); ​
 +
 + String strMainClass = String.format("​%2s",​ mainClass).replace('​ ', '​0'​); ​
 + sb.append(strMainClass);​
 +
 + sb.append(subclass); ​
 +
 + String strMainGroup = String.format("​%4s",​ mainGroup); ​
 + sb.append(strMainGroup); ​
 +
 + sb.append(SEPARATOR); ​
 +
 + sb.append(subgroup); ​
 +
 + return sb.toString(); ​
 + }
 +
 + public static void main(String[] args) {
 + char section = '​A'; ​
 + int mainClass = 4; 
 + char subclass = '​B'; ​
 + int mainGroup = 55; 
 + int subgroup = 56; 
 +
 + Ipc ipc = new Ipc(section,​ mainClass, subclass, mainGroup, subgroup); ​
 + System.out.println(ipc); ​
 + }
 +}
 +</​file>​
   * 上题的Ipc类至少要包含两个构造函数,其中一个构造函数有五个参数(分别为部、大类、小类、大组和小组),另一个构造函数只有一个参数(以字符串形式表示的IPC分类号)。   * 上题的Ipc类至少要包含两个构造函数,其中一个构造函数有五个参数(分别为部、大类、小类、大组和小组),另一个构造函数只有一个参数(以字符串形式表示的IPC分类号)。
 +【参考答案】
 +<file java Ipc.java>​
 +package cn.edu.bjut.chapter3;​
 +
 +public class Ipc {
 + private char section; ​
 + private int mainClass; ​
 + private char subclass; ​
 + private int mainGroup; ​
 + private int subgroup; ​
 +
 + private final char SEPARATOR = '/'; ​
 +
 + public Ipc(char section, int mainClass, char subclass, int mainGroup, int subgroup) {
 + this.section = section; ​
 + this.mainClass = mainClass; ​
 + this.subclass = subclass; ​
 + this.mainGroup = mainGroup; ​
 + this.subgroup = subgroup; ​
 + }
 +
 + // example: G09F 17/30
 + public Ipc(String symbol) {
 + this.section = symbol.charAt(0); ​
 + this.mainClass = Integer.parseInt(symbol.substring(1,​ 3)); 
 + this.subclass = symbol.charAt(3); ​
 +
 + int pos = symbol.indexOf(SEPARATOR); ​
 + this.mainGroup = Integer.parseInt(symbol.substring(4,​ pos).trim()); ​
 + this.subgroup = Integer.parseInt(symbol.substring(pos + 1)); 
 + }
 +
 + public char getSection() {
 + return section;
 + }
 +
 + public void setSection(char section) {
 + this.section = section;
 + }
 +
 + public int getMainClass() {
 + return mainClass;
 + }
 +
 + public void setMainClass(int mainClass) {
 + this.mainClass = mainClass;
 + }
 +
 + public char getSubclass() {
 + return subclass;
 + }
 +
 + public void setSubclass(char subclass) {
 + this.subclass = subclass;
 + }
 +
 + public int getMainGroup() {
 + return mainGroup;
 + }
 +
 + public void setMainGroup(int mainGroup) {
 + this.mainGroup = mainGroup;
 + }
 +
 + public int getSubgroup() {
 + return subgroup;
 + }
 +
 + public void setSubgroup(int subgroup) {
 + this.subgroup = subgroup;
 + }
 +
 + @Override
 + public String toString() {
 + StringBuilder sb = new StringBuilder(); ​
 +
 + sb.append(section); ​
 +
 + String strMainClass = String.format("​%2s",​ mainClass).replace('​ ', '​0'​); ​
 + sb.append(strMainClass);​
 +
 + sb.append(subclass); ​
 +
 + String strMainGroup = String.format("​%4s",​ mainGroup); ​
 + sb.append(strMainGroup); ​
 +
 + sb.append(SEPARATOR); ​
 +
 + sb.append(subgroup); ​
 +
 + return sb.toString(); ​
 + }
 +
 + public static void main(String[] args) {
 + char section = '​A'; ​
 + int mainClass = 4; 
 + char subclass = '​B'; ​
 + int mainGroup = 55; 
 + int subgroup = 56; 
 +
 + Ipc ipc = new Ipc(section,​ mainClass, subclass, mainGroup, subgroup); ​
 + System.out.println(ipc); ​
 +
 + String symbol = "G09F 17/​30"; ​
 + System.out.println(new Ipc(symbol)); ​
 + }
 +}
 +</​file>​
 +  * 定义一个StringUtils类,至少包括方法isIpc()和capitalize()等。
 +【参考答案】
 +<file java StringUtils.java>​
 +package cn.edu.bjut.utils;​
 +
 +public class StringUtils {
 + public final static char SEPARATOR = '/';​
 +
 + public static String capitalize(String str) {
 + if (str == null) {
 + return null; 
 +
 +
 + if (str.length() == 1) {
 + return str.toUpperCase(); ​
 + }
 +
 + return str.substring(0,​ 1).toUpperCase() + str.substring(1).toLowerCase(); ​
 + }
 +
 + public static boolean isIpc(String str) {
 + char section = str.charAt(0); ​
 + if (section < '​A'​ || section > '​H'​) {
 + return false; ​
 + }
 +
 + int mainClass = Integer.parseInt(str.substring(1,​ 3)); 
 + if (mainClass < 1 || mainClass > 99) {
 + return false; ​
 + }
 +
 + char subclass = str.charAt(3); ​
 + if (subclass < '​A'​ || subclass > '​Z'​) {
 + return false; ​
 + }
 +
 + int pos = str.indexOf(SEPARATOR); ​
 + int mainGroup = Integer.parseInt(str.substring(4,​ pos).trim()); ​
 + if (mainGroup < 1 || mainGroup > 9999) {
 + return false; ​
 + }
 +
 + int subgroup = Integer.parseInt(str.substring(pos + 1)); 
 + if (subgroup < 0 || subgroup > 99999) {
 + return false; ​
 + }
 +
 + return true; 
 + }
 +
 + public static void main(String[] args) {
 + String str = "​heLLO"; ​
 + System.out.println(StringUtils.capitalize(str)); ​
 +
 + String symbol = "G06F 17/​30"; ​
 + System.out.println(StringUtils.isIpc(symbol)); ​
 + }
 +}
 +</​file>​
 +  * 定义一个MathUtils类,至少包括方法sum()和LogSumExp()等。
 +注意:LogSumExp的计算公式为$y = \log \sum_i {e^{x_i}}$。
 +
 +该公式有以下两个问题:(1)当$x_i$有一个偏大时,$e^{x_i}$计算值会溢出(overflow),致使数值计算出现问题;(2)当$x_i$都偏小时,$\sum_i {e^{x_i}}$接近于0,对其计算log也会出现数值计算问题。
 +【参考答案】
 +<file java MathUtils.java>​
 +package cn.edu.bjut.utils;​
 +
 +public class MathUtils {
 + public static double logsum(double loga, double logb) {
 + double sum = (loga > logb)? ​
 + (loga + Math.log(1.0 + Math.exp(logb - loga))): (logb + Math.log(1.0 + Math.exp(loga - logb)));
 +
 + return sum; 
 + }
 +
 + public static void main(String[] args) {
 + double loga = 10; 
 + double logb = 1000; 
 +
 + double sum = MathUtils.logsum(loga,​ logb); ​
 + System.out.println(sum); ​
 + System.out.println(Math.exp(1000)); ​
 + }
 +}
 +</​file>​
  
 [[zh:​courses:​java2026:​index|返回Java课程页]] [[zh:​courses:​java2026:​index|返回Java课程页]]
  
 ~~DISCUSSION~~ ~~DISCUSSION~~
zh/courses/java2026/ch03.1773062523.txt.gz · 最后更改: 2026/03/09 21:22 由 pzczxs