Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Помогите решить задачку, верней билет. желательно с пояснениями

Ответить
Настройки темы
C/C++ - Помогите решить задачку, верней билет. желательно с пояснениями

Новый участник


Сообщения: 1
Благодарности: 0

Профиль | Отправить PM | Цитировать


Вариант 7
Описать класс с именем MARSH, содержащий следующие элементы:
• Поля: название начального пункта маршрута, название конечного пункта маршрута, номер
маршрута.
• Методы: конструктор по умолчанию, конструктор с тремя параметрами для заполнения всех
полей класса, конструктор копирования, деструктор, операция присваивания, операция
сравнения «меньше» (операция возвращает истину, если номер маршрута у первого операнда
меньше чем у второго, ложь - в противном случае), функция вывода на экран значений полей
класса.
Память для строк - полей класса выделять динамически.
с помощью текстового редактора создать файл и записать в него данные для массива из восьми
элементов типа MARSH.
Написать программу, выполняющую следующие действия:
• ввод из файла данных в динамический массив, состоящий из восьми элементов типа MARSH;
• упорядочить массив по возрастанию номеров маршрутов;
• вывод на экран информации о маршруте, номер которого введен с клавиатуры;
• если таких маршрутов нет, выдать на дисплей соответствующее сообщение.

Отправлено: 18:46, 04-01-2010

 
pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


С использованием стандартной библиотеки C++ будет выглядеть примерно так:
Код: Выделить весь код
#include <string>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <list>
using namespace std;

class March
{
public:
	// деструктор ~March(), который создаётся автоматически
        // вполне нас устраивает

	// автоматический конструктор копирования (почленное копирование) тоже годится.
	// автоматический оператор присваивания также должен работать почленно.

	March() : _number(unsigned()) {}
	// нужно для использования контейнеров

	March(string const& begin, string const& end, unsigned number) :
		_begin(begin), _end(end), _number(number)
	{
	}

	// оператор << лучше сделать внешним из логических соображений:
	// он равнозначно относится и в `a` и к `b`
	friend bool operator<(March const& a, March const& b)
	{
		return a._number < b._number;
	}

	friend ostream& operator<<(ostream& os, March const& a)
	{
		return os << __tag_begin << "\t" << a._begin << "\n"
			<< __tag_end	<< "\t" << a._end << "\n"
			<< __tag_number	<< "\t" << a._number << "\n";
	}

	friend istream& operator>>(istream& is, March& a)
	{
		string tag;

		// в случае неудачного чтения из потока (а именно несовпадения названий тэгов)
		// помечаем поток неверным (и прерываем дальнейшее его использование)
		// все остальные проверки нужны чтобы вовремя остановиться.
		if (!(is >> tag) || (tag!=__tag_begin) || !getline(is, a._begin) ||
			!(is >> tag) || (tag!=__tag_end) || !getline(is, a._end) ||
			!(is >> tag) || (tag!=__tag_number) || !getline(is, a._number))
		{
			is.setstate(ios::failbit);
		}

		// здесь скрыта потенциальная угроза порчи данных в исключительной ситуации:
		// когда класс March будет недопрочитан (например неправильный формат файла)
		// непрочитанные поля сохранят значения, с которыми они зашли в оператор чтения
		// из потока. Чтобы этого не случилось, желательно копировать элементы в контейнер,
		// а не читать прямо внутри его. Пример будет ниже.
		
		return is;
	}

	// публикуем для поиска
	unsigned number() const {return _number;}

private:
	string _begin, _end;
	unsigned _number;

	// так мы позволим менять форму ввода-вывода
	static string const __tag_begin, __tag_end, __tag_number;
};

string const March::__tag_begin("begin:"), March::__tag_end("end:"), March::__tag_number("number:");

void main()
{
	// в данном случае 2-связный список предпочтительней вектора
	// потому что класс March тяжело копируется (содержит 2 динамические строки)
	// для сортировки желательно использовать список либо вектор указателей.
	// Создаём список из 8 одинаковых элементов.
	list<March> marchs(8, March(string(), string(), 0U));

	{
		ifstream fin("data.txt");

		// загружаем данные от начала до конца списка
		for(list<March>::iterator out_first=marchs.begin(), out_last=marchs.end();
			out_first!=out_last && (fin>>*out_first); ++out_first)
		{
			// пример уязвимости при чтении: если при чтении 4-го элемента произойдёт сбой,
			// он останется недопрочитанным (сохранит значения, в данном случае присвоенные
			// по умолчанию).
		}
	}

	marchs.sort();

	// класс-функтор для поиска по номеру маршрута
	struct have_number_t
	{
		unsigned arg;
		have_number_t(unsigned arg1) : arg(arg1) {}
		bool operator()(March& a) {return a.number()==arg;}
	}

	cout << "Номер маршрута? " << flush;
	have_number_t search_number;
	cin >> search_number.arg;
	
	// поиск c использованием search_number.operator()();
	list<March>::iterator found=find_if(marchs.begin(), marchs.end(), search_number);

	if (found!=marchs.end())
	{
		cout << *found << "\n";
	}
	else
	{
		cout << "Не найдено\n";
	}
}
Но если использовать map<unsigned,March>, то March::operator<() не нужен, и всё намного проще:
Код: Выделить весь код
#include <map>
//using namespace std;

void main()
{
	map<unsigned,March> march_by_number;

	// класс map сразу использует сортированный список (точнее дерево)
	{
		ifstream fin("data.txt");
		
		// собираем вместе аргумент для map<unsigned,March>::insert()
		// на самом деле map<unsigned,March> хранит элементы не March,
		// а pair<unsigned,March>. Соответсвенно итератор контейнера map
		// будет указывать на элементы этого типа pair<...>. Первый в паре
		// будет ключом для поиска, второй - соотвествующим March.

		pair<unsigned,March> blank_march;

		for(unsigned n=0; n<8 && fin>>blank_march.second; ++n)
		{
			// готовим ключ для поиска
			blank_march.first = blank_march.second.number();

			// добавляем в сортированный список через копирование.
			// если произойдёт сбой, недочитанный blank_march
			// не будет помещён в контейнер. Таким образом,
			// march_by_number содержит только целостные данные.

			march_by_number.insert(blank_march);
		}
	}

	cout << "Номер маршрута? " << flush;
	unsigned search_number;
	cin >> search_number.arg;
	
	map<March>::iterator found=march_by_number.find(search_number);
	// можно было бы использовать map<...>::operator[](), но он добавляет
	// новые элементы, если таких не было раньше. Нам этого не нужно.

	if (found!=marchs.end())
	{
		// помним что итератор указывает на пару
		cout << found->second << "\n";
	}
	else
	{
		cout << "Не найдено\n";
	}
}

Последний раз редактировалось Drongo, 07-01-2010 в 15:02. Причина: Кое-что превратилось в смайл, использоватл тег - [noparse]...[/noparse]

Это сообщение посчитали полезным следующие участники:

Отправлено: 03:15, 07-01-2010 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Помогите решить задачку, верней билет. желательно с пояснениями

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
C/C++ - Помогите решить задачу Urann Программирование и базы данных 11 14-05-2013 11:44
Разное - Помогите решить задачку в Excel!! v-b Программирование и базы данных 7 04-04-2013 18:12
VBA - помогите решить задачку Vba + Excel hellp123 Программирование и базы данных 3 14-03-2009 01:15
C/C++ - Помогите решить elektra192 Программирование и базы данных 14 19-12-2007 18:00
Помогите решить проблему!!!! Guest Сетевые технологии 1 14-10-2004 23:46




 
Переход