一些有用的Notes_关于OOP_开卷考的参考资料

本文最后更新于:2024年10月25日 下午

programming 04 Text Processing

Q1:

Write a program to read a number of grades from the user. The user will first enter the number of grades that will be entered, then the grades. At the end, you should print out the average of the grades.

Notes:

  • You must give the user many more attempts when they have entered a value that is not an integer.
  • You must give the user many more attempts if they enter an integer value that is not acceptable (outside of the range 0 - 100).
  • When calculating the average, you should use a double (if you use float the answer might be slightly different).

Hint for allowing the user to make multiple attempts:

To allow the user many attempts to enter the correct type and a value in the correct range, you will need to use two nested loops, the outer loop should check if the text if the value is in the correct range and an inner loop that removes any tokens entered that are not the correct type.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.util.Scanner;

public class TryAgain {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int numGrades = in.nextInt();
double sum = 0;
for(int i = 0; i < numGrades; i++){
sum += getGrade(in);
}
System.out.println("The average grade was " + (sum/numGrades));
}

private static int getGrade(Scanner s){
int grade = 0;
while (grade == 0){
while(!s.hasNextInt()){
s.next();
}
grade = s.nextInt();
if (grade < 0 || grade > 100){
grade = 0;
}
}
return grade;
}
}

Q2:

Write a program to read some student information from the command prompt. This information should be used to create Student objects (based on this Student class).

Your program should contain the following operations: (you do not need to define the Student class, but do not forget to import the scanner)

  • Define and construct a scanner to read input from the user
  • Define and construct an array of Student objects of size 3
  • Read the first name of a student from the user and store it in a variable
  • Read the family name of a student from the user and store it in a variable
  • Read the number of a student from the user and store it in a variable
  • Read the age of a student from the user and store it in a variable
  • Read the name of the degree that the student is studying and store it in a variable
  • Construct a student object based on the values read from the user and store it in the array
  • Repeat the process two more times
  • In reverse order, print the student number and degree of each student on a single line
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.util.Scanner;

public class prog{
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Student[] students = new Student[3];
for (int i = 0; i < students.length; i++) {
String n = input.next();
String fn = input.next();
int sn = input.nextInt();
int a = input.nextInt();
String deg = input.nextLine();
students[i] = new Student(n, fn, sn, a, deg);
}

for (int i = students.length-1; i >= 0; i--) {
System.out.println(students[i].getStudentNumber() + " " + students[i].getDegreeName());
}
}
}

Programming 05 Encapsulation

Define a class named Time. This class should represent an instant in time during a day (as a number of hours, minutes and seconds) and provide some utility methods too.

The class should have the following functionality:

Constructors

  • A constructor that takes three int parameters in the order hours, minutes, seconds

Constants

  • A constant named SECONDS_PER_MINUTE, that has a value of 60
  • A constant named MINUTES_PER_HOUR, that has a value of 60
  • A constant named HOURS_PER_DAY, that has a value of 24

Instance Methods

  • A method named getSeconds, that takes no parameters and returns an int representing the number of seconds since the start of the last minute (0 - 59)
  • A method named getMinutes, that takes no parameters and returns an int representing the number of minutes since the start of the last hour (0 - 59)
  • A method named getHours, that takes no parameters and returns an int representing the number of hours since the start of the last day (0 - 23)
  • A method named timeBetween, that takes another Time object as a parameter and returns an int representing the number of seconds between these two times. The value should always be positive.
  • A method named sameTime, that takes another Time object as a parameter and returns a boolean value. The return value should be true if both time objects represent the same time and false if they do not.
  • A method named asString, that takes no parameters and returns a string containing the current time in the format hh:mm:ss
  • A method named setTime, that takes three int parameters in the order hours, minutes, seconds and returns nothing. This method should set the time to the values provided only if it represents a valid time.

Class Methods

  • A class method named isValidTime, that takes three int parameters in the order hours, minutes, seconds and returns a boolean value. The return value should be true if the values represent a valid time and false if they do not.

Notes

You should base this work on the earlier question in programming problems quiz 02. However, it is expected that you apply the knowledge learned from the lecture about encapsulation to the class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class Time {
public static final int MINUTES_PER_HOUR = 60;
public static final int SECONDS_PER_MINUTE = 60;
public static final int HOURS_PER_DAY = 24;
private int seconds;
public Time(int h, int m, int s) {
seconds = s + m * SECONDS_PER_MINUTE + h * MINUTES_PER_HOUR * SECONDS_PER_MINUTE;
}

public int getSeconds() {
return seconds % SECONDS_PER_MINUTE;
}

public int getMinutes() {
return (seconds % (MINUTES_PER_HOUR * SECONDS_PER_MINUTE)) / SECONDS_PER_MINUTE;
}

public int getHours() {
return seconds / (MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
}

public int timeBetween(Time t) {
return Math.abs(seconds - t.seconds);
}

public boolean sameTime(Time t) {
return t.seconds == seconds;
}
public String asString() {
return String.format("%02d:%02d:%02d", getHours(), getMinutes(), getSeconds());
}
public void setTime(int h, int m, int s) {
if (isValidTime(h, m, s)) {
seconds = s + m * SECONDS_PER_MINUTE + h * MINUTES_PER_HOUR * SECONDS_PER_MINUTE;
}
}

public static boolean isValidTime(int h, int m, int s) {
if (h < 0 || h >= HOURS_PER_DAY || m < 0 || m >= MINUTES_PER_HOUR || s < 0 || s >= SECONDS_PER_MINUTE) {
return false;
}
return true;
}

}

Programming 06 Interfaces

Your teacher has too many tasks to complete, and needs help with tracking them. Unfortunately, they tasks are all of different types but have some commonalities that can be extracted to the following interface:

1
2
3
4
5
public interface Timeable {
String getTaskName();
int getTaskRating();
Duration getTaskTime();
}

The first method returns a string containing a description of the task to be completed. The second method returns a rating indication how much the person desires to complete the task as a number between 1 and 5 (inclusive). The final method returns a Duration object detailing the amount of time the task will take to complete.

Write a class called TaskManager that can be used to track the details of some tasks. The class should have the following methods:

  • public void addTask(Timeable t)
  • public Timeable getHighestRated()
  • public Timeable getLowestRated()
  • public Timeable getShortestTask()
  • public Timeable getLongestTask()
  • public Duration getTotalDuration()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import java.time.Duration;
public class TaskManager {
Timeable highestRated;
Timeable lowestRated;
Timeable shortestTask;
Timeable longestTask;
Duration totalTime = Duration.ZERO;

public void addTask(Timeable c) {
if (highestRated == null) {
highestRated = c;
lowestRated = c;
shortestTask = c;
longestTask = c;
}
if (c.getTaskRating() > highestRated.getTaskRating()) {
highestRated = c;
}
if (c.getTaskRating() < lowestRated.getTaskRating()) {
lowestRated = c;
}
if (c.getTaskTime().toMillis() < shortestTask.getTaskTime().toMillis()) {
shortestTask = c;
}
if (c.getTaskTime().toMillis() > longestTask.getTaskTime().toMillis()) {
longestTask = c;
}
totalTime = totalTime.plus(c.getTaskTime());
}

public Timeable getHighestRated() {
return highestRated;
}

public Timeable getLowestRated() {
return lowestRated;
}

public Timeable getShortestTask() {
return shortestTask;
}

public Timeable getLongestTask() {
return longestTask;
}

public Duration getTotalDuration() {
return totalTime;
}
}

Programming 07 Inheritance and Text Processing

Question 1 :雇员问题

Given the Employee and PayrollSystem classes. Complete the following classes:

  1. A class named SalariedEmployee which inherits from the Employee class
  2. A class named HourlyPaidEmployee which inherits from the Employee class
  3. A class named Contractor which inherits from the Employee class
  4. A public class named Main, which contains a main method
Numbers

All numbers in this example are calculated in cents. There are 100 cent in 1 euro. This is because it is always a bad idea to use floating point numbers for money. As such all values should be calculated and returned as integers.

Employee Class

The Employee class is abstract and contains an abstract method for calculating the weekly payroll cost of an employee. This must be implemented in the subclasses that you define. The Employee class also contains a getTax method, which calculates tax as 10% of the weekly payroll cost of an employee.

SalariedEmployee

This class is very similar to an Employee, except it also should be able to remember the salary of the employee and use this to calculate the weekly payroll cost. Note that salaries are stated by the amount of money the person will earn in one year, you will need to calculate how much that will cost per week.

HourlyPaidEmployee

This class is very similar to an Employee, except it also should be able to remember the hourly wage of an employee and the number of hours they work every week. These values should be used to calculate the weekly payroll cost for these employees.

Contractor

A contractor is a special type of employee who is paid to complete a task, but the company does not have to pay any tax for them.

Main Class

Write a program that completes the following steps

  1. Reads each line of user input and creates the appropriate type of employee object
  2. Add all of the employee objects to an array (there will be a maximum of 100)
  3. Use the calculateTotalWeeklyPayroll and calculateTotalWeeklyTax methods in the PayrollSystem class to calculate and output those values.
Input Text

The input from the user will contain the information about a single employee on each line. The line will start with the word “Salary” it the employee is paid a salary, “Hourly” if the employee is paid an hourly rate, and “Contractor” if the employee is a contractor.

Lines containing information about a salaried employee will contain the following values separated by spaces:

  1. The employees name (just one word)
  2. The employees id number (a string starting with the letter P)
  3. The employees salary as an integer in cents

Lines containing information about a hourly paid employees will contain the following values separated by spaces:

  1. The employees name (just one word)
  2. The employees id number (a string starting with the letter P)
  3. The employees hourly rate of pay as an integer in cents
  4. The number of hours that this employee works every week

Lines containing information about a contractor will contain the following values separated by spaces:

  1. The contractors name (just one word)
  2. The contractors id number (a string starting with the letter P)
  3. The contractors amount that is paid to the contractor every week in cents.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import java.util.Scanner;

public class Main {
public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);
Employee[] employees = new Employee[100];
int count = 0;
while (scanner.hasNext()) {
String line = scanner.nextLine();

String[] data = line.split(" ");
String type = data[0];
if (type.equals("Salary")) {
String name = data[1];
String employeeId = data[2];
int salary = Integer.parseInt(data[3]);
employees[count] = new SalariedEmployee(name, employeeId, salary);
count++;
} else if (type.equals("Hourly")) {
String name = data[1];
String employeeId = data[2];
int hourlywage = Integer.parseInt(data[3]);
int weeklyhours = Integer.parseInt(data[4]);
employees[count] = new HourlyPaidEmployee(name, employeeId, hourlywage, weeklyhours);
count++;

} else if (type.equals("Contractor")) {
String name = data[1];
String employeeId = data[2];
int payment = Integer.parseInt(data[3]);

employees[count] = new Contractor(name, employeeId, payment);
count++;
}
}
PayrollSystem payrollSystem = new PayrollSystem();
int payroll = payrollSystem.calculateTotalWeeklyPayroll(employees);
int tax = payrollSystem.calculateTotalWeeklyTax(employees);
System.out.println("Total weekly payroll: " + payroll);
System.out.println("Total weekly tax: " + tax);

count = 0;
employees = new Employee[100];
}


public static class SalariedEmployee extends Employee {
int salary;

public SalariedEmployee(String name, String employeeId, int salary) {
super(name, employeeId);
this.salary = salary;
}

@Override
public int getWeeklyPayroll() {
return salary / 52;
}


}

public static class HourlyPaidEmployee extends Employee {
int hourlywage;
int weeklyhours;

public HourlyPaidEmployee(String name, String employeeId, int hourlywage, int weeklyhours) {
super(name, employeeId);
this.hourlywage = hourlywage;
this.weeklyhours = weeklyhours;
}

@Override
public int getWeeklyPayroll() {
return hourlywage * weeklyhours;
}


}

public static class Contractor extends Employee {
int payment;

public Contractor(String name, String employeeId, int payment) {
super(name, employeeId);
this.payment = payment;
}

@Override
public int getWeeklyPayroll() {
return payment;
}


@Override
public int getTax() {
return 0;
}
}
}

Question 2: 日期时间问题

Given the Time class. Define a class named Instant that inherits from the Time class. The instant class should add the functionality to remember an amount of milliseconds along with a value of hours, minutes and seconds.

To this class you should add the following methods:

  1. a toString method which takes no parameters and returns a string containing the representation from the time object followed by milliseconds (this should use the inherited toString method from the Time class)
  2. a sameInstant method which takes an Instant object as a parameter and returns boolean if both objects represent the same time (this should use the inherited sameTime method from the Time class)
  3. a milliSecondsBetween method takes an Instant object as a parameter and returns and int value representing the difference between the two instants counted in miliseconds (this should use the inherited timeBetween method from the Time class)

In addition, you should define a public class named Main. In this class you should define the following static methods:

  • A method named readAndTestToString that reads four space separated integers from the user and uses them to create an Instant object. This object should then be printed to the screen.
    • The numbers will be in the order hours minutes seconds milliseconds
  • A method named readAndTestSameInstant that reads two lines of space separated integers from the user and uses them to create instant objects. A message should be printed to the screen if the two objects represent the same instant.
  • A method named readAndTestMilliSecondsBetween that reads two lines of space separated integers from the user and uses them to create instant objects. A message should be printed to the screen showing the number of milliseconds between the two instant objects.

The Time class has the following public interface.

1
2
3
4
5
6
7
public Time(int h, int m, int s)
public int getSeconds()
public int getMinutes()
public int getHours()
public int timeBetween(Time t)
public boolean sameTime(Time t)
public String toString()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class Instant extends Time {
private int milliSeconds;

public Instant(int h, int m, int s, int ms) {
super(h, m, s);
milliSeconds = ms;
if (milliSeconds > 999) {
milliSeconds = 0;
}
}

public int milliSecondsBetween(Instant i){
return Math.abs(i.milliSeconds - milliSeconds) + timeBetween(i)*1000;
}

public boolean sameInstant(Instant i) {
return i.milliSeconds == milliSeconds && super.sameTime(i);
}

public String toString() {
return super.toString() + String.format(".%03d", milliSeconds);
}
}
class Main {
public static void readAndTestToString(){
Scanner s = new Scanner(System.in);
Instant a = new Instant(s.nextInt(), s.nextInt(), s.nextInt(), s.nextInt());
System.out.println(a);
}

public static void readAndTestMilliSecondsBetween(){
Scanner s = new Scanner(System.in);
Instant a = new Instant(s.nextInt(), s.nextInt(), s.nextInt(), s.nextInt());
Instant b = new Instant(s.nextInt(), s.nextInt(), s.nextInt(), s.nextInt());
System.out.println(a + " and " + b + " are "+a.milliSecondsBetween(b)+" millisecond apart");
}

public static void readAndTestSameInstant(){
Scanner s = new Scanner(System.in);
Instant a = new Instant(s.nextInt(), s.nextInt(), s.nextInt(), s.nextInt());
Instant b = new Instant(s.nextInt(), s.nextInt(), s.nextInt(), s.nextInt());
if (a.sameInstant(b)){
System.out.println(a + " and " + b + " are the same instant");
} else {
System.out.println(a + " and " + b + " are not the same instant");
}
}

public static void main(String[] args) {
readAndTestToString();
}
}

Programming 08 Files and Text Proc.

问题描述:

01 - readTextFile:定义一个叫做readTextFile的方法,接受文件名字符串作为参数,读取文件内容,返回不包含空白行的字符串数组。文件最多包含1000行。

02 - getTableOfContents:定义一个名为getTableOfContents的静态/类方法,接受文件名字符串作为参数。使用前面问题中的readTextFile方法获取文件内容。文件中包含 LaTeX 命令,表示教科书的章节结构。从中提取出章节、节、子节和子子节的名称,并按规定的格式添加标识符,将它们作为列表返回。

  • 如果是章节名称,在字符串前添加”# “。
  • 如果是节名称,在字符串前添加”## “。
  • 如果是子节名称,在字符串前添加”### “。
  • 如果是子子节名称,在字符串前添加”#### “。

LaTeX命令的格式如下:\section{节的名称}\subsection{子节的名称}\subsubsection{子子节的名称}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;


public class readTextFile {
public static String[] readTextFile(String fileName){
String[] lines = new String[1000];
try (BufferedReader br = new BufferedReader(new FileReader(fileName))){
// like
// FileReader fr = new FileReader(name);
// BufferedReader bf = new BufferedReader(dr);
String line;
int lineCount = 0;
while ((line = br.readLine()) != null && lineCount < lines.length){
if (!line.trim().isEmpty()) {
lines[lineCount++] = line;
}
}
} catch (FileNotFoundException e) {
System.out.println("E");
} catch (IOException e) {
e.printStackTrace();
System.err.println("The file named " + fileName+" was not found.");
}

return lines;

}


public static String[] getTableOfContents(String fileName){
String[] lines = readTextFile(fileName);
String[] contents = new String[1000];
int contentscount = 0;

try {
for(String line : lines) {
if (line != null) {
if (line.startsWith("\\chapter{")) {
contents[contentscount++] = "# " + getCommandContent(line);
} else if (line.startsWith("\\section{")) {
contents[contentscount++] = "## " + getCommandContent(line);
;
} else if (line.startsWith("\\subsection{")) {
contents[contentscount++] = "### " + getCommandContent(line);
;
} else if (line.startsWith("\\subsubsection{")) {
contents[contentscount++] = "#### " + getCommandContent(line);
;
}
}
}


} catch (NullPointerException e) {
e.printStackTrace();

}
return contents;
}

private static String getCommandContent(String line) {
// Extract the content inside the curly braces of the latex command
int startIndex = line.indexOf('{') + 1;
int endIndex = line.lastIndexOf('}');
return line.substring(startIndex, endIndex);
}

public static void main(String[] args) {
String[] lines = readTextFile("chapter1.tex");
System.out.println(lines[0]);
System.out.println(lines[45]);
System.out.println(lines[80]);
System.out.println(lines[150]);
System.out.println(lines[178]);
}
}

Programming 09 Generics/Collections

Given the Time class, modify it such that it can be sorted using the sort methods from Arrays or Collections. This should be done by implementing the Comparable interface with the correct type parameter.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
class Time implements Comparable<Time> {
private int seconds;
private int minutes;
private int hours;
public Time(int h, int m, int s) {
if (seconds < 0 || seconds > 59) {
throw new IllegalArgumentException("Seconds must be between 0 and 59");
}
if (minutes < 0 || minutes > 59) {
throw new IllegalArgumentException("Minutes must be between 0 and 59");
}
if (hours < 0 || hours > 23) {
throw new IllegalArgumentException("Hours must be between 0 and 23");
}
seconds = s;
minutes = m;
hours = h;
}

public int getSeconds() {
return seconds;
}

public int getMinutes() {
return minutes;
}

public int getHours() {
return hours;
}

public String toString() {
return String.format("%02d:%02d:%02d", getHours(), getMinutes(), getSeconds());
}

@Override
public int compareTo(Time o) {
if (this.hours > o.hours) {
return 1;
} else if (this.hours < o.hours) {
return -1;
} else {
if (this.minutes > o.minutes) {
return 1;
} else if (this.minutes < o.minutes) {
return -1;
} else {
if (this.seconds > o.seconds) {
return 1;
} else if (this.seconds < o.seconds) {
return -1;
} else {
return 0;
}
}
}
}
}

Given the Time class which you may not modify, create a comparator (named TimeComparator) which implements the Comparator interface with the correct type parameter. The result should be that time objects can be sorted using the sort methods from Arrays or Collections. The time values should be sorted into descending order.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class TimeComparator implements Comparator<Time> {
public int compare(Time t1, Time t2) {
if (t1.getHours() > t2.getHours()) {
return -1;
} else if (t1.getHours() < t2.getHours()) {
return 1;
} else {
if (t1.getMinutes() > t2.getMinutes()) {
return -1;
} else if (t1.getMinutes() < t2.getMinutes()) {
return 1;
} else {
if (t1.getSeconds() > t2.getSeconds()) {
return -1;
} else if (t1.getSeconds() < t2.getSeconds()) {
return 1;
} else {
return 0;
}
}
}
}
}