Консультация № 184929
22.12.2011, 22:23
500.00 руб.
0 1 1
Здравствуйте, уважаемые эксперты! Прошу переработать программу в приложение с учётом 3его пункта задания. Пожалуйста, сделайте как можно быстрей. С наступающим праздником!
Задание:
1. Разработать класс "множество символов" в соответствии со следующим заданием:
Состояние класса -
Множество состоит из элементов типа char (в множестве не может быть двух элементов с одинаковыми значениями) и определяется мощностью (количеством элементов в множестве) и значениями своих элементов, например: множество из 6 элементов - строка abcdef. Память под множество выделяется статически, во время компиляции, и задается массивом фиксированного предельного значения (например, максимальная мощность множества 100 элементов).
Протокол класса -
Определяет возможности создания и инициализации экземпляров класса и правила использования их (методы класса).
Предусмотреть следующие возможности:
• пустой конструктор для инициализации экземпляров и массивов экземпляров класса по умолчанию;
• создание экземпляров класса с инициализацией мощностью множества (начальное множество - символы, начиная с символа пробел);
• создание экземпляров класса с инициализацией значениями элементов множества как строки символов;
• ввод экземпляров класса из входного потока и вывод их значений в выходной поток
(с помощью перегруженных операторов >> и << );
• объединение двух множеств (с помощью перегруженного оператора сложения +; результирующее множество должно содержать элементы множества 1 и отличающиеся элементы множества 2);
• добавление нового элемента в множество (с помощью перегруженного оператора += );
• вычисление пересечения двух множеств (с помощью перегруженного оператора умножения *; результирующее множество должно состоять из элементов, имеющихся и в множестве 1, и в множестве 2);
• вычисление разности двух множеств (с помощью перегруженного оператора вычитания -; результирующее множество должно состоять из элементов первого множества без тех, которые есть во втором множестве);
• определение, имеется ли некоторый заданный элемент в множестве.
2. Проектирование класса рекомендуется начать с представления состояния класса, учитывающего заданные операции, а затем реализации конструкторов и перегруженного оператора вывода. Для отладки и исчерпывающего тестирования других методов разработанного класса реализовать диалоговую программу, которая позволяет вводить параметры, отлаживаемых методов.
3. Повторить разработку класса при условии, что память под множество выделяется необходимой длины динамически, во время выполнения программы (с помощью оператора new; память задается указателем на char в состоянии класса).
Дополнить интерфейс класса следующими возможностями:
• создание экземпляра класса с его инициализацией другим экземпляром класса (копирующий конструктор);
• переопределение экземпляра класса (с помощью перегруженного оператора присваивания).

4. Написать прикладную программу, использующую разработанный класс.


Приложение:
//Set.h
#pragma once
#include <iostream>
using namespace std;

class Set
{
static const int max_power = 100; //максимальная мощность
char set [max_power]; //массив символов
int power; //мощность
public:
Set () : power(0) {}; //• пустой конструктор для инициализации экземпляров и массивов экземпляров класса по умолчанию;
Set (const Set& s); //конструктор копирования
Set (int p); //• создание экземпляров класса с инициализацией мощностью множества (начальное множество - символы, начиная с символа пробел);
Set (const char* str);//• создание экземпляров класса с инициализацией значениями элементов множества как строки символов;
~Set () {}; //деструктор

Set& operator = (const Set& s); //оператор присваивания
Set& operator += (const char e);//• добавление нового элемента в множество (с помощью перегруженного оператора += );
bool In (char e) const;//• определение, имеется ли некоторый заданный элемент в множестве.

friend Set operator - (const Set &p1, const Set &p2); //• вычисление разности двух множеств (с помощью перегруженного оператора вычитания -; результирующее множество должно состоять из элементов первого множества без тех, которые есть во втором множестве);
friend Set operator * (const Set &p1, const Set &p2); //• вычисление пересечения двух множеств (с помощью перегруженного оператора умножения *; результирующее множество должно состоять из элементов, имеющихся и в множестве 1, и в множестве 2);
friend Set operator + (const Set &p1, const Set &p2); //• объединение двух множеств (с помощью перегруженного оператора сложения +; результирующее множество должно содержать элементы множества 1 и отличающиеся элементы множества 2);
friend istream & operator >> ( istream & in, Set & p ); // ввод экземпляров класса из входного потока
friend ostream & operator << ( ostream & out, const Set & p ); // вывод в выходной поток
};

//set.cpp
#include "StdAfx.h"
#include "Set.h"

Set::Set (const Set& s)
{
power = s.power; //копируем мощность
memcpy (set, s.set, sizeof(char)*power); //копируем данные
}

Set::Set (int p)
{
if (p>max_power) { //если переданная мощность больше максимальной
power = 0; //инициализируем по умолчанию
return;
}
power = p; //сохраняем мощность
for (int i = 0; i<p; i++) //заполняем символами от пробела
set[i] = ' '+i;
}

Set::Set (const char* str)
{
power = 0; //обнуляем мощность
int len = strlen (str); //получаем длину строки
if (len > max_power) return; //если она больше максимальной - выходим
for (int i = 0; i<len; i++) //Заполняем символами из строки
*this+=str[i];
}

Set& Set::operator = (const Set& s)
{ //аналогично конструктору копирования
power = s.power;
memcpy (set, s.set, sizeof(char)*power);
return *this;
}

Set& Set::operator += (const char e)
{
if (power+1>max_power || In(e)) return *this; //если максимальная мощность достигнута или такой элемент уже есть - выходим
set[power] = e; //Добавляем в конец
power++; //увеличиваем мощность
}

bool Set::In (char e) const
{
for (int i = 0; i<power; i++) //ищем символ в массиве
if (set[i] == e) return true; //нашли - возвращаем 1
return false; //не нашли - 0
}

Set operator - (const Set &p1, const Set &p2)
{
Set tmp; //буфер
for (int i = 0; i<p1.power; i++) //идём по символам первого множества
if (!p2.In(p1.set[i])) tmp+=p1.set[i]; //если символ первого не содержится во втором, добавляем к результату
return tmp; //возвращаем буфер
}

Set operator * (const Set &p1, const Set &p2)
{
Set tmp;
for (int i = 0; i<p1.power; i++) //если символ первого содержится во втором, добавляем к результату
if (p2.In(p1.set[i])) tmp+=p1.set[i];
return tmp;
}

Set operator + (const Set &p1, const Set &p2)
{
Set tmp;
for (int i = 0; i<p1.power; i++) //просто добавляем к результату все символы первого и второго множеств
tmp+=p1.set[i]; //повторные не добавятся из-за реализации оператора +=
for (int i = 0; i<p2.power; i++)
tmp+=p2.set[i];
return tmp;
}

istream & operator >> ( istream & in, Set & p )
{
cout << "Enter power: ";
in >> p.power;
cout << "Enter chars: ";
for (int i=0; i<p.power; i++)
in >> p.set[i];
return in;
}

ostream & operator << ( ostream & out, const Set & p )
{
out << "{ ";
for (int i = 0; i<p.power-1; i++)
out << p.set[i] << ", ";
out << p.set[p.power-1] << " }";
return out;
}




/*int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}*/

//12.cpp
#include "StdAfx.h"
#include "Set.h"
#include <conio.h>
#include <stdlib.h>
Set s2;
Set s3("01234567");




char Menu ()
{
system ("cls");
cout << "1. Vyvod stand stroki.\n2.Dobavlenie novyh elementov vo mnozhestvo(+=).\n3.Vvod iz vhodnogo potoka - >>.\n4.Slojenie strok.\n5.Vychitanie strok.\n6.Umnojenie strok.\n7.Poisk elementa.\n8.Exit.\n";
cout << "Enter menu item: ";
char c;
cin >> c;
return c;
}



void f1()
{
Set s1("01234567");
cout << "\ns1:\n" << s1;
cout << "\nPress any key to continue.";
_getch ();
}
void f2()
{ char k;
cout << "Vvedite elementy stroki"<<endl;
for (char i='5'; i<='9'; i++)
{
cin >> k;
s2+=k;
}
cout << "\ns1:\n" << s2;
cout << "\nPress any key to continue.";
_getch ();
}
void f3()
{
cout << "\ns1:\n" << s3;
cout << "\ns2:\n" << s2;
cout << "\ns1+s2: \n" << s2+s3;
_getch ();
}
void f4()
{
cout << "\ns1:\n" << s3;
cout << "\ns2:\n" << s2;
cout << "\ns1-s2: \n" << s3-s2;
_getch ();
}
void f5()
{
cout << "\ns1:\n" << s3;
cout << "\ns2:\n" << s2;
cout << "\ns1*s2: \n" << s3*s2;
_getch ();
}
void f6()
{ char d;
cout << "Vvedite element"<<endl;
cin >> d;
if (s3.In (d)==true)
cout << "Element naiden";
else
cout << "Element NE naiden";
_getch ();
}

void f7 ()
{
cin >> s2;
cout << "\ns1:\n" << s2;
cout << "\nPress any key to continue.";
_getch ();
}

int _tmain(int argc, _TCHAR* argv[])
{
bool b = true;
while (b) {
try
{
char c = Menu ();
switch (c)
{
case '1': f1();
break;
case '2': f2();
break;
case '3': f7();
break;
case '4': f3();
break;
case '5': f4();
break;
case '6': f5();
break;
case '7': f6();
break;
case '8': b = false;
break;
}
}
catch (char* ex)
{
cout << ex;
}
}

return 0;
}

Обсуждение

Неизвестный
27.12.2011, 14:05
общий
это ответ
Здравствуйте, Посетитель - 383089!
Собственно, разница только в использовании динамической памяти внутри класса, поэтому основную программу можно вообще не менять. Я сделала в лоб, при добавлении элемента память перевыделяется. Если Вам нужен более оптимальный вариант, когда память не по одному символу выделяется, а блоками, пишите, я переделаю.

Код в приложении, проверен на MSVS 2005.

Удачи!

Приложение:
//Set.h
#pragma once
#include <iostream>
using namespace std;

class Set
{
char* set; //массив символов
int power; //мощность
public:
Set () : power(0), set(NULL) {}; //• пустой конструктор для инициализации экземпляров и массивов экземпляров класса по умолчанию;
Set (const Set& s); //конструктор копирования
Set (int p); //• создание экземпляров класса с инициализацией мощностью множества (начальное множество - символы, начиная с символа пробел);
Set (const char* str);//• создание экземпляров класса с инициализацией значениями элементов множества как строки символов;
~Set (); //деструктор

Set& operator = (const Set& s); //оператор присваивания
Set& operator += (const char e);//• добавление нового элемента в множество (с помощью перегруженного оператора += );
bool In (char e) const;//• определение, имеется ли некоторый заданный элемент в множестве.

friend Set operator - (const Set &p1, const Set &p2); //• вычисление разности двух множеств (с помощью перегруженного оператора вычитания -; результирующее множество должно состоять из элементов первого множества без тех, которые есть во втором множестве);
friend Set operator * (const Set &p1, const Set &p2); //• вычисление пересечения двух множеств (с помощью перегруженного оператора умножения *; результирующее множество должно состоять из элементов, имеющихся и в множестве 1, и в множестве 2);
friend Set operator + (const Set &p1, const Set &p2); //• объединение двух множеств (с помощью перегруженного оператора сложения +; результирующее множество должно содержать элементы множества 1 и отличающиеся элементы множества 2);
friend istream & operator >> ( istream & in, Set & p ); // ввод экземпляров класса из входного потока
friend ostream & operator << ( ostream & out, const Set & p ); // вывод в выходной поток
private:
void IncSize (); //увеличение размера множества на 1
};

//set.cpp
#include "StdAfx.h"
#include "Set.h"


Set::~Set ()
{
if (set!=NULL) delete [] set; //очистка памяти
}

Set::Set (const Set& s)
{
power = s.power; //копируем мощность
set = new char [power]; //выделение памяти
memcpy (set, s.set, sizeof(char)*power); //копируем данные
}

Set::Set (int p)
{
power = p; //сохраняем мощность
set = new char [power];
for (int i = 0; i<p; i++) //заполняем символами от пробела
set[i] = ' '+i;
}

Set::Set (const char* str)
{
power = strlen (str); //получаем длину строки
set = new char [power];
for (int i = 0; i<power; i++) //Заполняем символами из строки
*this+=str[i];
}

Set& Set::operator = (const Set& s)
{ //аналогично конструктору копирования
power = s.power;
if (set!=NULL) delete [] set;
set = new char [power];
memcpy (set, s.set, sizeof(char)*power);
return *this;
}

void Set::IncSize ()
{
power++; //увеличиваем мощность
if (set==NULL) { //если множество пустое, просто выделяем память
set = new char [power];
return; //и выходим
}
char* s1 = set; //сохраняем старый адрес
set = new char [power]; //выделяем память под новый размер
memcpy (set, s1, sizeof(char)*(power-1)); //копируем элементы
delete [] s1; //очищаем старую память
}

Set& Set::operator += (const char e)
{
if (In(e)) return *this; //если такой элемент уже есть - выходим
IncSize();
set[power-1] = e; //Добавляем в конец
}

bool Set::In (char e) const
{
for (int i = 0; i<power; i++) //ищем символ в массиве
if (set[i] == e) return true; //нашли - возвращаем 1
return false; //не нашли - 0
}

Set operator - (const Set &p1, const Set &p2)
{
Set tmp; //буфер
for (int i = 0; i<p1.power; i++) //идём по символам первого множества
if (!p2.In(p1.set[i])) tmp+=p1.set[i]; //если символ первого не содержится во втором, добавляем к результату
return tmp; //возвращаем буфер
}

Set operator * (const Set &p1, const Set &p2)
{
Set tmp;
for (int i = 0; i<p1.power; i++) //если символ первого содержится во втором, добавляем к результату
if (p2.In(p1.set[i])) tmp+=p1.set[i];
return tmp;
}

Set operator + (const Set &p1, const Set &p2)
{
Set tmp;
for (int i = 0; i<p1.power; i++) //просто добавляем к результату все символы первого и второго множеств
tmp+=p1.set[i]; //повторные не добавятся из-за реализации оператора +=
for (int i = 0; i<p2.power; i++)
tmp+=p2.set[i];
return tmp;
}

istream & operator >> ( istream & in, Set & p )
{
cout << "Enter power: ";
in >> p.power;
if (p.set!=NULL) delete [] p.set;
p.set = new char [p.power];
cout << "Enter chars: ";
for (int i=0; i<p.power; i++)
in >> p.set[i];
return in;
}

ostream & operator << ( ostream & out, const Set & p )
{
out << "{ ";
for (int i = 0; i<p.power-1; i++)
out << p.set[i] << ", ";
out << p.set[p.power-1] << " }";
return out;
}

Форма ответа