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

Обсуждение

Неизвестный
24.02.2009, 21:11
общий
необходимо решить на стандартных массивах или можно применять STL и ооп C++?
Неизвестный
25.02.2009, 22:46
общий
это ответ
Здравствуйте, 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
----------------------------------------------------------
Форма ответа