Второй семестр

Тур де Франс

Наша задача состоит в том, чтобы написать красивую объектно-ориентированную программу, которая будет заниматься обработкой данных результатов велогонки Тур де Франс. Данные гонки хранятся в трех текстовых файлах.

Файл 1 tdf14_teams.txt

В нем перечислены участники и команды. В каждой строке файла хранится запись вида:

национальность фамилия имя год_рождения номер команда

Например

SUI ALBASINI Michael 1980 182 ORICA GREENEDGE

Каждый участник однозначно идентифицируется по своему имени, а команда по названию (т.е. дубликатов нет)

Файл 2 tdf14_stages.txt

В нем перечислены этапы гонки в виде:

номер_этапа дата место_отправления место_прибытия дистанция

Например

1 05/07/14 Leeds Harrogate 190

Файл 3 tdf14_ranks.txt

В этом файле содержатся рейтинги участников на разных этапах. Каждая строка содержит следующее:

Номер_этапа место_участника номер_участника время_участника

Участники, сошедшие с дистанции во время этапа с номером i, где (1 ≤ i ≤ 21) исключены из рейтингов для всех последующих этапов.

Пример строки

1 198 76 04:58:16

Класс-обертка для чтения из файла прилагается.

import java.io.*;
 
public class ReadData {
	private BufferedReader reader;	// читатель из файла
 
	/**
	 * Конструктор.
	 */
	public ReadData() {
		reader = null;
	}
 
	/**
	 * открывает текстовый файл
	 * @param fileName имя файла
	 * @return true если открыли успешно, false иначе.
	 */
	public boolean open(String fileName) {
		try {
			FileReader fr = new FileReader(fileName);
			reader = new BufferedReader(fr);
			return true;
		}
		catch(IOException ex) {
			return false;
		}
	}
 
	/**
	 * Читает строку из файла, открытого методом open()
	 * @return прочитанная строка или null, если прочитать не удалось
	 */
	public String readLine() {
		try {
			return reader.readLine();
		}
		catch(IOException ex) {
			return null;
		}
	}
 
	/**
	 * Закрывает файл
	 */
	public void close() {
		if (reader != null) {
			try {
				reader.close();
			}
			catch(IOException ex) {
			}
		}
	}
}

Работа делится на две части. Первая заключается в создании системы классов и объектов для представления данных и начальном заполнении их информацией из файла. Вторая в статистической обработке данных.

Часть 1

Наша задача состоит в обработке файла tdf14_teams.txt. Для этого требуется создать следующие 4 класса.

  • Racer У нашего участника есть имя, фамилия, национальность, год рождения и номер участия. В классе должны быть необходимые геттеры и сеттеры, а так же метод int age(int year), который позволяет вычислить возраст участника, год передается в качестве параметра (например 2014)

public class Racer {
	String name;
	String surname;
	String nationality;
	int yearOfBirth;
	int number;
 
	public int getNumber() {
		return number;
	}
 
	public void setNumber(int number) {
		this.number = number;
	}
 
	public int getYearOfBirth() {
		return yearOfBirth;
	}
 
	public void setYearOfBirth(int year) {
		this.yearOfBirth = year;
	}
 
	public String getName() {
		return name;
	}
 
	public void setName(String name) {
		this.name = name;
	}
 
	public String getSurname() {
		return this.suername;
	}
 
	public void setSurname(String surname) {
		this.surname = surname;
	}
 
	public String getNationality() {
		return this.nationality;
	}
 
	public void setNationality(String nationality) {
		this.nationality = nationality;
	}
 
	public int age(int year) {
		return year - yearOfBirth;
	}
} 

  • Team Команда имеет название и список участников. Должны быть реализованы следующие методы:
    • Team(String name) конструктор, который принимает в качестве аргумента название команды. Список гонщиков инициализируется пустным списком
    • void insert(Racer racer) добавляет гонщика в команду
    • String getName() геттер для названия команды
    • int numberOfRacers() возвращает количество гонщиков в команде
    • Racer getRacers(int i) возвращает гонщика по номеру. Нумерация идет с нуля.
    • int totalAge(int year) возвращает суммарный возраст участников. Год передается в качестве параметра.

public class Team {
	String name;
	ArrayList<Racer> racers;
 
	public Team(String name) {
		this.name = name;
		racers = new ArrayList<Racer>();
	}
 
	public void insert(Racer racer) {
		racers.add(racer);
	}
 
	public String getName() {
		return this.name;
	}
 
	public int numberOfRacers() {
		return racers.size();
	}
 
	public Racer getRacers(int i) { 
		return racers.get(i);
	}
 
	public int totalAge(int year) {
		int sum = 0;
		for(Racer racer : racers) {
			sum = sum + racer.totalAge(year);
		}
		return sum;
	}
}

  • TeamsList Класс для списка команд. Должны быть реализованы следующие методы:
    • TeamsList() конструктор, инициализирующий список команд пустым списком.
    • void insert(Team team) добавляет команду в общий список.
    • Team getTeam(String teamName) возвращает команду по ее названию. Если такой команды не найдено, должен возвращаться null.
    • int numberOfTeams() возвращает количество команд
    • Team getTeam(int i) возвращает i-ю команду. Нумерация с нуля.
  • TourDeFrance главный класс программы, содержащий метод main. В этом классе должны выполнятся вызовы методов для чтения данных о велосипедистах, создаваться необходимые объекты (участники, команды, список команд), показываться информация о командах и их участниках. После чтения данных и заполнения объектов нужно ответить на вопрос: каков средний возраст участников Тур де Франс 2014. Ответ округлить до двух знаков после запятой. Набросок для этого класса приведен далее.

public class TourDeFrance {
	/**
	 * Метод для создания гонщика, на основани файла с списком гонщиков/команд
	 * @param line одна строка из файла
	 * @param teamsList список команд, который заполняется на основании строки из файла
	 */
	public static void parceTeamLine(String line, TeamsList teamsList) {
		// Элементы в строках нашего файла разделени знаками табуляции, их мы
		// и будем использовать чтобы отличить один элемет от другого. 
		String[] elem = line.split("\t");
 
		// Информация о гонщике
		String nat = elem[0];
		String racerFamilyName = elem[1];
		String racerName = elem[2];
		int year = Integer.parseInt(elem[3]);
		int number = Integer.parseInt(elem[4]);
		String teamName = elem[5];
 
		// TODO Найти команду по имени в списке
		// TODO Если не найдено, то создать команду и добавить в список
		// TODO Создать гонщика и добавить в команду
	}
 
	/**
	 * Метод для создания команд
	 * @param  fileName Имя файла для команд
	 * @param  teamsList список команд
	 * @return если чтение данных прошло успешно, то возвращается true (это значит,
	 * 		   что все команды/участники прочитаны и занесены в список)
	 *		   В противном случае возвращается false
	 */
	public static boolean createTeams(String fileName, TeamsList teamsList) {
		// Объект, связанный с файлом, откуда мы будем построчно читать данные
		ReadData reader = new ReadData();
 
		if (reader.open(fileName)) {
			// Пропустим заголовок
			String line = reader.readLine();
 
			// Обработаем строку для добавления в список
			while ((line = reader.readLine()) != null) {
				parceTeamLine(line, teamsList);
			}
			reader.close();
			return true;	// все прошло хорошо
		}
		else {
			return false;	// или плохо
		}
	}
 
	/**
	 * Главный метод 
	 * @param args аргументы командной строки
	 */
	public static void main(String[] args) {
		final int currentYear = 2014;
		final String teamsFileName = "tdf14_teams.txt";
 
		// TODO Создать список команд (и инициализировать!)
 
		// Обработка файла с командами
		boolean res = createTeams(teamsFileName, temsList);
		if (!res) {
			System.out.println("Произошла ошибка с чтением списка команд");
		}
		else {
			// TODO Оставшаяся часть программы (вывести данные, чтобы удостовериться в корректном чтении файла,
			// вычислить средний возраст участников и т.д.
		}
	}
}

Часть 2

Задача – это обработать файлы tdf14_stages.txt and tdf14_ranks.txt чтобы ответить на различные вопросы, к примеру:

  1. Какова общая дистанция, которую проехали гонщики? А средняя?
  2. Найти самый длинный и самый короткий этапы
  3. Кто выиграл этап, который начинается в городе Mulhouse? Кто выиграл этап, который заканчивается в городе Risoul? Кто выиграл этап 14 июля?
  4. Какова тройка победителей 2014 года? Какова общая таблица зачета?
  5. Какое общее время потребовалось участникам команды FDJ.FR на завершение гонки? И какое общее время, для 3 лучших каждого этапа?
  6. Кто из участников по своей воле сошел с дистанции и на каких этапах?
  7. На каких этапах среднее время участников, которые не сошли с дистанции, было самым малым?
  8. Кто из участников набрал наибольшую среднюю скорость на том или ином этапе, и на каком этапе?
  9. В какой команде участники двигаются с одинаковой скоростью (т.е. время на этап примерно одинаковое)? Каков разрыв между самым слабым и самым сильными гонщиками команд?
java/vtoroj_semestr.txt · Последние изменения: 09/02/2015 11:20 — ybezrukov
CC Attribution-Noncommercial 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0