2022_Programming Exam_开卷考参考文档

本文最后更新于:2024年1月5日 晚上

image-20231214104329639

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
public class Q1 {

public static String diagonals(int size, int gap, char char1, char char2) {
String pattern = "";
if(char1 == char2){
throw new IllegalArgumentException();
}
if (size < 7 || size > 31){
throw new IllegalArgumentException();
}
if (gap < 1){
throw new IllegalArgumentException();
}
for(int i = 0; i < size; i++){
for (int j = 0; j < size; j++){
if (i == j || (j-i) % (gap + 1) == 0){
pattern += char1;
}else {
pattern += char2;
}

if(j == size - 1 && i != size-1){
pattern += "\n";
}
}
}
return pattern;
}

public static void main(String[] args) {
System.out.println(Q1.diagonals(10, 3, '+', ' '));
System.out.println(Q1.diagonals(12, 1, 'X', '!'));
}
}

Question 2: Modelling and Processing Files and Objects
The world cup is currently under way, but the organisers have been very forgetful. They need a
system to help them keep track of the progress of the tournament and determine which teams
have won in the groups and which games should be played next.

a. Define a class named FootballTeam which implements the Team interface provided. This
class will be used to keep track of the progress of teams in the group stages of the
tournament. This means we need to be able to remember or calculate all of the relevant
statistics. The methods in the FootballTeam class should be implemented based on the
following descriptions:
•public String getName() - Returns the name of the team
•public int getWins() - Returns the number of games the team has won
•public int getLosses() - Returns the number of games the team has lost
•public int getDraws() - Returns the number of games the team has drawn
•public int getPoints() - Returns the number of points the team has scored (3
for a win, 1 for a draw and 0 for a loss)
•public int getGoalsFor() - Returns the number of goals that this team has scored
in all of their games
•public int getGoalsAgainst() - Returns the number of goals that other teams
have scored when playing this team
•public int addGame(Game g) - Adds the result of a game that was played by this
team.1 In order to function in the testing system, you must also add a constructor
with the following signature:
public FootballTeam(String name).

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
public class FootballTeam implements Comparable<FootballTeam>, Team {
private final String name;
private int wins;
private int draws;
private int losses;
private int goalsFor;
private int goalsAgainst;
private int points;

public FootballTeam(String name) {
this.name = name;
}

@Override
public String getName() {
return name;
}

@Override
public void addGame(Game game) {
Result result = game.getResult(this);
if (result == Result.WIN) {
wins++;
points += 3;
} else if (result == Result.DRAW) {
draws++;
points++;
} else {
losses++;
}
goalsFor += game.getGoalsFor(this);
goalsAgainst += game.getGoalsAgainst(this);
}

@Override
public int getWins() {
return wins;
}

@Override
public int getLosses() {
return losses;
}

@Override
public int getDraws() {
return draws;
}

@Override
public int getPoints() {
return points;
}

public int compareTo(FootballTeam other) {
if (this.getPoints() > other.getPoints()) {
return -1;
} else if (this.getPoints() < other.getPoints()) {
return +1;
} else {
if (this.getGoalsFor() - this.getGoalsAgainst() > other.getGoalsFor() - other.getGoalsAgainst()) {
return -1;
} else if (this.getGoalsFor() - this.getGoalsAgainst() < other.getGoalsFor() - other.getGoalsAgainst()) {
return +1;
} else {
if (this.getGoalsFor() > other.getGoalsFor()) {
return -1;
} else if (this.getGoalsFor() < other.getGoalsFor()) {
return +1;
} else {
return this.name.compareTo(other.name);
}
}
}
}

@Override
public int getGoalsFor() {
return goalsFor;
}

@Override
public int getGoalsAgainst() {
return goalsAgainst;
}
}

语法

1
public int compareTo( NumberSubClass referenceName )

参数

referenceName – 可以是一个 Byte, Double, Integer, Float, Long 或 Short 类型的参数。

返回值

  • 如果指定的数与参数相等返回 0。
  • 如果指定的数小于参数返回 -1。
  • 如果指定的数大于参数返回 1。

b. Define a class named FootballGame which implements the Game interface provided. This
class will be used to remember the statistics of a single game in the tournament between
two teams. The methods in the FootballGame class should be implemented based on the
following descriptions:
•public Result getResult(Team team) - Returns the result of the game (Result.WIN,
Result.LOSS, or result.DRAW) for the team passed as a parameter
•public int getGoalsFor(Team team) - Returns the number of goals that were
scored by the team passed as a parameter
•public int getGoalsAgainst(Team team) - Returns the number of goals that
were against by the team passed as a parameter
For all of these methods, if the team parameter that is passed does not match either of
the teams in the game then an IllegalArgumentException should be thrown.

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
public class FootballGame implements Game{
private Team teamA;
private Team teamB;
private int scoreA;
private int scoreB;

public FootballGame(Team teamA, int scoreA, Team teamB, int scoreB){
this.teamA = teamA;
this.teamB = teamB;
this.scoreA = scoreA;
this.scoreB = scoreB;
}

@Override
public Result getResult(Team a) {
if (!a.equals(teamA) && !a.equals(teamB)) {
throw new IllegalArgumentException();
}

if (a.equals(teamA)) {
if (scoreA > scoreB) {
return Result.WIN;
} else if (scoreA < scoreB) {
return Result.LOSS;
} else {
return Result.DRAW;
}
} else if (a.equals(teamB)) {
if (scoreA > scoreB) {
return Result.LOSS;
} else if (scoreA < scoreB) {
return Result.WIN;
} else {
return Result.DRAW;
}
}
return null;
}

@Override
public int getGoalsFor(Team a) {
if (a.equals(teamA)) {
return scoreA;
} else {
return scoreB;
}
}

@Override
public int getGoalsAgainst(Team a) {
if (a.equals(teamA)) {
return scoreB;
} else {
return scoreA;
}
}
}

c. Define a class named WorldCupGroup which implements the Group interface provided.
This class will be used to determine which teams can progress to the next round of the
tournament as well as producing the table of results. The methods in the WorldCupGroup
class should be implemented based on the following descriptions:
•public Team getWinner() - Returns the team object of the team that came first
in the group
•public Team getRunnerUp() - Returns the team object of the team that came
second in the group
•public String getTable() - Returns a string containing the current table for the
group.
The getTable method should have output in the following format. The group name
should be on the first line, the column headers should be on the second line, and the
teams and their statistics should be on the remaining lines. An example of the output is
given here:
image-20231214112811984
In this the following abbreviations are made:
•W - For the number of games the team has won
•D - For the number of games the team has drawn
•L - For the number of games the team has lost
•F - For the number of goals the team has scored
•A - For the number of goals that have been scored against this team
•P - For the number of points the team has scored
The teams should be primarily ordered from largest to smallest by points. If teams are
equal on points, then they should be secondarily ordered by goal difference (F - A).
Finally, if all of these are equal then they should be orders based on their names. All
of the methods in this class rely on the ability to correctly order the teams in this way.
Consider what approach you will use to sort the objects into the correct order.
In order to function in the testing system, you must also add a constructor with the
following signature:
public WorldCupGroup(String groupName, Team a, Team b, Team c, Team d)

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
public class WorldCupGroup implements Group{
private String groupName;
private Team a;
private Team b;
private Team c;
private Team d;


public WorldCupGroup(String groupName, Team a, Team b, Team c, Team d){
this.groupName = groupName;
this.a = a;
this.b = b;
this.c = c;
this.d = d;
}

@Override
public String getName() {
return groupName;
}

@Override
public String getTable() {
Team[] teams = new Team[] {a, b, c, d};
Team winner = getWinner();
Team runnerUp = getRunnerUp();
String table = "";
table += ("Group " + getName() + ":\n");
table += String.format("%-20s %3s %3s %3s %3s %3s %3s \n", "Team", "W", "D", "L", "A", "P");
table += formatTableRow(winner);
table += formatTableRow(runnerUp);

Team third = null;
for (Team i : teams) {
if (i != winner && i != runnerUp) {
if (third == null || (i.getPoints() > third.getPoints()) || (i.getPoints() == third.getPoints() && (i.getGoalsFor() - i.getGoalsAgainst()) > (third.getGoalsFor() - third.getGoalsAgainst())) || (i.getPoints() == winner.getPoints() && i.getGoalsFor() - i.getGoalsAgainst() == winner.getGoalsFor() - winner.getGoalsAgainst() && i.getName().compareTo(winner.getName()) < 0)) {
third = i;
table += formatTableRow(third);
} else {
table += formatTableRow(i);
}
}
}
return table;
}

private String formatTableRow(Team team) {
return String.format("%-20s %3d %3d %3d %3d %3d %3d\n",
team.getName(), team.getWins(), team.getDraws(), team.getLosses(),
team.getGoalsFor(), team.getGoalsAgainst(), team.getPoints());
}


@Override
public Team getWinner() {
Team[] teams = new Team[] {a,b,c,d};
Team winner = a;
for (Team i :teams){
if (i.getPoints() > winner.getPoints() ||
(i.getPoints() == winner.getPoints() && i.getGoalsFor() - i.getGoalsAgainst() > winner.getGoalsFor() - winner.getGoalsAgainst()) ||
(i.getPoints() == winner.getPoints() && i.getGoalsFor() - i.getGoalsAgainst() == winner.getGoalsFor() - winner.getGoalsAgainst() && i.getName().compareTo(winner.getName()) < 0)){
winner = i;
}
}
return winner;
}

@Override
public Team getRunnerUp() {
Team[] teams = new Team[] {a,b,c,d};
Team winner = getWinner();
Team runnerup = null;
for (Team i : teams){
if(i != winner) {
if (runnerup == null ||
(i.getPoints() == runnerup.getPoints() && i.getGoalsFor() - i.getGoalsAgainst() > runnerup.getGoalsFor() - runnerup.getGoalsAgainst()) ||
i.getPoints() > runnerup.getPoints()){
runnerup = i;
}
}
}
return runnerup;
}
}

image-20231214113031322

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class KnockoutFixture implements Fixture{
private Team teamA;
private Team teamB;

public KnockoutFixture(Team teamA, Team teamB){
this.teamA = teamA;
this.teamB = teamB;
}
@Override
public String toString(){
String info = teamA.getName()+" vs "+teamB.getName();
return info;
}
}

image-20231214113124254

image-20231214113141623

image-20231214113202035

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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;


public class Q2 {
public static void readGroups(String filename, Map<String, Team> teams, Map<String, Group> groups) {
try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
String line;
while ((line = reader.readLine()) != null) {
String[] data = line.split(",");

String groupName = data[0];

for (int i = 1; i < data.length; i++) {

String teamName = data[i];
Team team = new FootballTeam(teamName);
teams.put(teamName, team);
}

Group group = new WorldCupGroup(groupName, teams.get(data[1]), teams.get(data[2]), teams.get(data[3]), teams.get(data[4]));
groups.put(groupName, group);
}


} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e){
e.printStackTrace();
throw new RuntimeException(e);
}
}


public static void readGames(String filename, Map<String, Team> teams, List<Game> games){
try (BufferedReader reader = new BufferedReader(new FileReader(filename))){
String line;
while ((line = reader.readLine()) != null){
String[] data = line.split(",");
String teamAName = data[0];
String teamBName = data[2];

Team teamA = teams.get(teamAName);
Team teamB = teams.get(teamBName);

int scoreA = Integer.parseInt(data[1]);
int scoreB = Integer.parseInt(data[3]);

Game game = new FootballGame(teamA,scoreA,teamB,scoreB);

teamA.addGame(game);
teamB.addGame(game);

games.add(game);
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e){
e.printStackTrace();
throw new RuntimeException(e);
}
}


/*public static void calculateKnockouts(Map<String,Group> groups, List<Fixture> fixtures){
List<Team> winners = new ArrayList<>();
List<Team> runnerUps = new ArrayList<>();

for (Group group : groups.values()){
winners.add(group.getWinner());
runnerUps.add(group.getRunnerUp());
}

for (int i = 0; i < winners.size(); i++) {
Fixture KnockoutFixture = null;
if (i % 2 == 0) {
Team teamA = winners.get(i);
Team teamB = runnerUps.get(i + 1);
KnockoutFixture = new KnockoutFixture(teamA, teamB);
} else {
Team teamA = winners.get(i);
Team teamB = runnerUps.get(i - 1);
KnockoutFixture = new KnockoutFixture(teamA, teamB);
}
fixtures.add(KnockoutFixture);

}
}*/

public static void calculateKnockouts(Map<String, Group> groups, List<Fixture> fixtures){
fixtures.add(new KnockoutFixture(groups.get("A").getWinner(), groups.get("B").getRunnerUp()));
fixtures.add(new KnockoutFixture(groups.get("B").getWinner(), groups.get("A").getRunnerUp()));

fixtures.add(new KnockoutFixture(groups.get("C").getWinner(), groups.get("D").getRunnerUp()));
fixtures.add(new KnockoutFixture(groups.get("D").getWinner(), groups.get("C").getRunnerUp()));

fixtures.add(new KnockoutFixture(groups.get("E").getWinner(), groups.get("F").getRunnerUp()));
fixtures.add(new KnockoutFixture(groups.get("F").getWinner(), groups.get("E").getRunnerUp()));

fixtures.add(new KnockoutFixture(groups.get("G").getWinner(), groups.get("H").getRunnerUp()));
fixtures.add(new KnockoutFixture(groups.get("H").getWinner(), groups.get("G").getRunnerUp()));

}

public static void main(String[] args) {
Map<String, Team> teams2 = new TreeMap<>();
Map<String, Group> groups2 = new TreeMap<>();
List<Game> games2 = new ArrayList<>();
List<Fixture> fixtures2 = new ArrayList<>();

Q2.readGroups("groups.txt", teams2, groups2);
Q2.readGames("games.txt", teams2, games2);
//System.out.println("Group num "+ groups2.size());
//System.out.println("Team num " + teams2.size());
Q2.calculateKnockouts(groups2, fixtures2);

//System.out.println(groups2.get("A").getWinner().getName());
//System.out.println(groups2.get("A").getWinner().getGoalsFor());
//System.out.println(groups2.get("A").getRunnerUp().getName());
//System.out.println(groups2.get("B").getWinner().getName());
//System.out.println(groups2.get("C").getWinner().getName());
//System.out.println(groups2.get("D").getWinner().getName());
//System.out.println(groups2.get("A").getTable());

//System.out.println();


List<String> games1 = fixtures2.stream().map(Fixture::toString).collect(Collectors.toList());
Collections.sort(games1);
for (String s : games1) {
System.out.println(s);
}
}

}