这里会显示出您选择的修订版和当前版本之间的差别。
| 后一修订版 | 前一修订版 | ||
|
zh:courses:java2026:ch03 [2026/03/09 21:15] pzczxs 创建 |
zh:courses:java2026:ch03 [2026/03/30 19:18] (当前版本) pzczxs [上机作业] |
||
|---|---|---|---|
| 行 1: | 行 1: | ||
| ====== 第三章:类与对象 ====== | ====== 第三章:类与对象 ====== | ||
| ===== 课件 ===== | ===== 课件 ===== | ||
| - | 下载:类与对象 | + | 下载:{{ :zh:courses:java2026:ch03.pptx |类与对象}} |
| ===== Point类 ===== | ===== Point类 ===== | ||
| 行 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~~ | ||