Консультация онлайн # 161299

Раздел: С / С++
Автор вопроса: dmi_5116
Дата: 24.02.2009, 16:32 Консультация неактивна
Поступило ответов: 1
Здравствуйте уважаемые эксперты!!!! Помогите пожалуйста решить задачу:
Сведения о кубике состоит из длины ребра в см, его цвета и названия материала, из которого он изготовлен. Дан массив сведений о кубиках. Создать массив сведений о колличестве и суммарном обьеме кубиков каждого из цветов.Заранее спасибо!

Ответ # 1, Micren (Посетитель)

Здравствуйте, dmi_5116!
Вот программа на C++ с уклоном на ООП. Без использования векторов STL. Все построено на манипуляциях с массивами.
Код
#include <locale>
#include <limits>
#include <iostream>
#include <iomanip>
#include <exception>
#include <string>

using namespace std;

// Это класс-кубик
class Cube
{
public:
	// Конструктор с параметрами:ребро,цвет и материал
	Cube(double Edge,wstring Color,wstring Material=L"")
		:_edge(Edge)
		,_color(Color)
		,_material(Material)
	{
		if(!(Edge>0))
			throw CubeClassException(L"Длина ребра куба должна быть больше нуля");
		if(!Color.length())
			throw CubeClassException(L"Не задана обязательная информация о цвете");
		// Сделаем первую букву цвета заглавной, остальные строчные
		_color[0]=towupper(_color[0]);
		for(unsigned int i=1;i<_color.length();i++)
			_color[i]=towlower(_color[i]);
	};
	// Возвращает данные о цвете
	const wstring& color()const
	{
		return _color;
	}
	// Возвращает даные о длине ребра
	const double edge()const
	{
		return _edge;
	}
	// Класс-исключение
	// Здесь используется один раз в конструкторе 
	// Делал, скорее, для примера, чем для какой-либо реальной цели
	class CubeClassException:exception
	{
	public:
		CubeClassException(const wchar_t* const msg=L"Неверный аргумент")
			:_msg(msg)
		{
		}
		virtual const wchar_t* const whatHappens()const
		{
			return _msg;
		}
	private:
		const wchar_t* const _msg;
	};
private:
	double _edge;
	wstring _color,_material;
};

// Класс данных о цвете(тех данных, которые необходимо хранить по условию)
class ColorData
{
public:
	// Конструктор создает объект заданного цвета
	ColorData(wstring Color,double Edge=0)
		:_color(Color)
		,_volume(Edge*Edge*Edge)
		,_count(1)
	{}
	// Добавляет данные 
	void AddData(double Edge)
	{
		// Счетчик кубиков
		_count++;
		// Суммарный объем
		_volume+=Edge*Edge*Edge;
	}
	// Возвращает информацию о цвете
	const wstring& color()const
	{
		return _color;
	}
	friend wostream& operator<<(wostream& stream,const ColorData& data);
private:
	wstring _color;
	double _volume;
	unsigned int _count;
};

// Список данных о каждом цвете
class ColorCubeList
{
public:
	// Конструктор
	// Можно задать начальную емкость списка, но не обязательно это делать
	ColorCubeList(unsigned int Count=0)
		:_colorArray(0)
		,_capacity(Count)
		,_length(0)
	{
		// Если емкость не задана сам конструктор проявит некоторый интеллект
		if(!_capacity)_capacity=4;
		// Создаем массив указателей на объекты типа ColorData
		_colorArray=new ColorData*[_capacity];
	}
	// Деструктор
	virtual ~ColorCubeList()
	{
		if(_colorArray)
		{
			// Освобождаем память
			for(unsigned int i=0;i<_length;i++)
				delete _colorArray[i];
			delete[]_colorArray;
			_colorArray=0;
		}
	}
	// Добавляет информацию о кубике
	void Add(const Cube& cube)
	{
		// Получаем цвет кубика
		wstring color=cube.color();
		// Ищем есть ли информация о цвете в списке
		for(unsigned int i=0;i<_length;i++)
			if(_colorArray[i]->color()==color)
			{
				// Если есть просто добавим данные
				_colorArray[i]->AddData(cube.edge());
				return;
			}
		// Если нет, то необходимо добавить информацию о цвете
		// Если вся доступная емкость списка уже занята
		if(_length==_capacity)
		{
			// Расширим список
			_capacity<<=1;
			// Выделим новую область памяти
			ColorData** newData=new ColorData*[_capacity];
			// Скопируем наш массив указателей в новую область
			for(unsigned int i=0;i<_length;i++)
				newData[i]=_colorArray[i];
			// Освободим старую область памяти
			delete[]_colorArray;
			// Наш указатель должен указывать на новую область
			_colorArray=newData;
		}
		// Добавим информацию о цвете
		_colorArray[_length++]=new ColorData(color,cube.edge());
	}
	friend wostream& operator<<(wostream& stream,const ColorCubeList& list);
private:
	unsigned int _capacity;
	unsigned int _length;
	ColorData** _colorArray;
};

void line()
{
	wcout<<L"----------------------------------------------------------"<<endl;
}

// Перегруженный оператор вывода для списка
wostream& operator<<(wostream& stream,const ColorCubeList& list)
{
	if(list._length)
	{
		for(unsigned int i=0;i<list._length;i++)
		{
			stream<<*list._colorArray[i];
			line();
		}
	}
	else stream<<L"В списке нет данных";
	return stream;
}

// Перегруженный оператор вывода для класса информации о цвете
wostream& operator<<(wostream& stream,const ColorData& data)
{
	stream<<L"Цвет:"<<data._color<<endl;
	stream<<L"Количество:"<<data._count<<endl;
	stream<<L"Общий объем:"<<data._volume<<endl;
	return stream;
}

// Функция-шаблон для ввода чисел(и не только) разных типов
template<class T>
T inputNum(const wchar_t* const msg)
{
	T data=0;
	while(true)
	{
		wcout<<msg;
		wcin>>data;
		if(wcin.fail())
		{
			wcout<<L"Ошибочный ввод"<<endl;
			wcin.clear();
			wcin.ignore(numeric_limits<streamsize>::max(),L'\n');
		}
		else
		{
			wcin.ignore(numeric_limits<streamsize>::max(),L'\n');
			return data;
		}
	}
}

int main()
{
	locale::global(locale("rus_rus.866"));
	// Задаем количество кубиков
	unsigned int N=inputNum<unsigned int>(L"Введите количество кубиков:");
	try
	{
		// Выделим память под массив
		Cube** cubes=new Cube*[N];
		for(unsigned int i=0;i<N;i++)cubes[i]=0;
		// Ввод информации о кубиках
		for(unsigned int i=0;i<N;i++)
		{
			while(true)
			{
				line();
				wcout<<L"Для "<<i+1<<L"-го кубика введите данные:"<<endl;
				double edge=inputNum<double>(L"Длина ребра:");
				wstring color,material;
				wcout<<L"Цвет кубика:";
				getline(wcin,color);
				wcout<<L"Материал:";
				getline(wcin,material);
				try
				{
					cubes[i]=new Cube(edge,color,material);
					break;
				}
				catch (Cube::CubeClassException e)
				{
					wcout<<L"Ошибка:"<<e.whatHappens()<<endl;
				}
			}
		}
		line();
		// Далее обработка введенных данных
		// Список цветов
		ColorCubeList colorList;
		// Просто добавляем кубики
		for(unsigned int i=0;i<N;i++)
			colorList.Add(*cubes[i]);
		// И выводим результат
		wcout<<L"Получены следующие данные о цветах кубиков:"<<endl;
		line();
		wcout<<colorList;
		// Не забываем освободить память
		for(unsigned int i=0;i<N;i++)
			if(cubes[i])delete cubes[i];
		delete[]cubes;		
	}
	catch (bad_alloc)
	{
		// Обработка ошибок выделения памяти
		wcout<<L"Не могу выделить память"<<endl;
	}
	system("PAUSE");
	return 0;
}

Вот пример работы программы:
Код
Введите количество кубиков:8
----------------------------------------------------------
Для 1-го кубика введите данные:
Длина ребра:1
Цвет кубика:красный
Материал:дуб
----------------------------------------------------------
Для 2-го кубика введите данные:
Длина ребра:3
Цвет кубика:зеленый
Материал:сталь
----------------------------------------------------------
Для 3-го кубика введите данные:
Длина ребра:6
Цвет кубика:красный
Материал:бетон
----------------------------------------------------------
Для 4-го кубика введите данные:
Длина ребра:9
Цвет кубика:синий
Материал:пластилин
----------------------------------------------------------
Для 5-го кубика введите данные:
Длина ребра:10
Цвет кубика:синий
Материал:стекло
----------------------------------------------------------
Для 6-го кубика введите данные:
Длина ребра:синий
Ошибочный ввод
Длина ребра:5
Цвет кубика:синий
Материал:пластмасса
----------------------------------------------------------
Для 7-го кубика введите данные:
Длина ребра:6
Цвет кубика:белый
Материал:бумага
----------------------------------------------------------
Для 8-го кубика введите данные:
Длина ребра:7
Цвет кубика:белый
Материал:мел
----------------------------------------------------------
Получены следующие данные о цветах кубиков:
----------------------------------------------------------
Цвет:Красный
Количество:2
Общий объем:217
----------------------------------------------------------
Цвет:Зеленый
Количество:1
Общий объем:27
----------------------------------------------------------
Цвет:Синий
Количество:3
Общий объем:1854
----------------------------------------------------------
Цвет:Белый
Количество:2
Общий объем:559
----------------------------------------------------------

Micren

Посетитель
25.02.2009, 22:46
Нет оценки ответа

Мини-форум консультации # 161299

Micren

177678

= общий =    24.02.2009, 21:11
необходимо решить на стандартных массивах или можно применять STL и ооп C++?
Возможность оставлять сообщения в мини-форумах консультаций доступна только после входа в систему.
Воспользуйтесь кнопкой входа вверху страницы, если Вы зарегистрированы или пройдите простую процедуру регистрации на Портале.