Формулировка задания
Требуется разработать объектно-ориентированную программу для вычисления объединения(суммы) и пересечения(произведения) двух любых подмножеств латинских букв. Заданные подмножества латинских букв должны передаваться программе через аргументы командной строки ее вызова. Программная реализация вычислений должна быть основана на разработке класса множества символов с перегрузкой операторов '+' и '*' для выполнения соответствующих теоретико-множественных операций.
Результатом работы программы, то есть результат операции должен отображаться символьной строкой в потоке стандартного вывода. Для удобства отображения результата в программе должна быть предусмотрена перегрузка оператора ‘<<’ класса потока стандартного вывода для объектов класса множества латинских букв.
Программа должна быть составлена в системе программирования C++ на основе разработки специального класса, в котором перегружены специальные операции над двумя любыми подмножествами латинских букв.
|
|
Свойства подмножеств
Вычислительная обработка подмножеств латинских букв основана на использовании 2-х операций: объединения(суммы) и пересечения(произведения). Для выполнения этих операций символическое представление подмножества выражается символьной строкой из латинских букв. Пусть Ml и М2 обозначают подмножества латинских букв, а МЗ-результируюшее подмножество, результат операции. Тогда выполнение теоретико-множественных операций над подмножествами латинских букв выражают следующие соотношения:
· Произведение(пересечение): ABC * CDA = AC
· Сложение(объединение):ABC + CDA = ABCD
Программирование операций над подмножествами латинских букв
При разработке программы выполнения теоретико-множественных операций целесообразно сосредоточить описание подмножеств и операции их обработки в отдельном классе Set. Класс Set должен содержать частные (private) компоненты данные и общедоступные (public) компонентные методы обработки приватных данных. Это позволит оперировать данными класса Set только в компонентных методах и исключит возможность непосредственного обращения к ним из любой внешней функции программы. Исходя из этого, декларация логической структуры класса Set должна иметь следующий формат:
class Set {
private: /* спецификация компонентных данных */
public: /* объявление прототипов компонентных методов */
};
В приватную часть класса Set следует включить беззнаковое целое, биты которого соответствуют буквам латинского алфавита. Причем единичный бит означает, что соответствующая его позиция в слове латинских букв (в алфавитном порядке) входит в данное множество. Например, асе представляется следующим образом:
|
|
(е)(с)(а)
1 0 1 0 1
Тогда битовые операции над битами этого поля эквивалентны операциям над элементами множеств.
Таким образом, структура класса множеств Set выглядит следующим образом:
class Set { private:
unsigned wordset; /*беззнаковое целое*/ public:
................
};
В общедоступную часть декларации класса Set нужно включить объявление прототипов компонентных методов, которые реализуют обработку подмножеств и отображение результатов обработки. Кроме того, в общедоступной части следует объявить конструктор класса с аргументом, где аргумент - это строка символов, обозначающих заданное подмножество и конструктор без аргументов.
Желаемую обработку подмножеств латинских букв удобно реализовать с помощью компонентных оператор-функций, которые обеспечат перегрузку операций (+,*) в выражениях с объектами класса Set. Наличие оператор-функций позволит конструировать выражения для объектов класса Set в наглядной форме как для объектов простых типов. При наличии соответствующих оператор-функций будет правильно вычисляться, например, следующее выражение программы:
r=f1@f2;
где r, f1 и f2 объекты класса Set, а @ - знак операции.
По формату определения и декларации оператор-функция идентична обычной функции с предопределенным именем operator@, где @ обозначает знак перегружаемой операции, и специальным соглашением по аргументам. Для декларации 2-х требуемых оператор-функций в классе Set может быть рекомендован следующий идентичный формат:
Set operator@(Set &); который отличается только символом перегружаемой операции @ (+,*). Используя эти декларации, компилятор языка C++ будет рассматривать приведенное выше выражение как следующий вызов соответствующей компонентной оператор-функции:
r=f1.ореrаtor@(f2);
Как видно из приведённой спецификации вызова, аргумент компонентной оператор-функции используется для передачи по ссылке 2-го операнда операции. Первый операнд операции неявно передается через скрытый аргумент, присущий любой компонентной функции и доступный по указателю this. Результат вычислений в теле оператор-функции возвращается в основную программу для присвоения объекту класса Set. Следует отметить, что передача аргумента по ссылке в данном случае выбрана из экономических соображений. Для оператор-функции допустима передача аргумента по значению. Однако, в этом случае происходит создание промежуточной копии объекта передачи в стеке оператор-функции.
Перегрузка оператора >> используется для вывода результата.
Для инициализации компонентных данных при создании объектов класса Set в нем предусмотрен конструктор с аргументом типа указатель на строку символов (char*). Поэтому декларация конструктора в общественной части объявления класса Set должен иметь следующий формат:
Set (char*str){…./* Преобразование str в битовый формат */ }
Через аргумент в этот конструктор должно передаваться представление подмножества латинских букв в виде строки символов. Конструктор должен преобразовывать символьное представление подмножества латинских букв в битовые значения компонент-данных класса Set.
Рассмотренные общедоступные компоненты класса Set можно использовать в основной функции main(int argc,char** argv) программы выполнения теоретико-множественных операций. Вычисляемое выражение должно передаваться в функцию main через параметры командной строки вызова программы.
В теле функции main следует задать 3 объекта класса Set для хранения операндов и результата операции. Объекты- операнды должны быть инициализированы строками соответствующих параметров командной стоки. Объект результата можно инициализировать третьей строкой.
Знак операции, передаваемый в функцию main через 2-й параметр командной строки, удобно рассматривать в операторе switch системы программирования C++ для выбора одного из 2-х вариантов вычисляемых дробных выражений. После вычисления выбранного выражения с помощью соответствующей компонентной оператор-функции класса Set ответ нужно сохранить в зарезервированном объекте-результате. Вызов оператор-функции >> класса Set от имени объекта результата, позволит отобразить полученную дробь в потоке стандартного вывода.
|
|
Пример 1
Общий вид кода программы
Class Set{
private:
unsigned wordset;
public:
Set(char*str {.../*Преобразование str в битовый формат*/})
Set() {wordset <- 0 }
Set operator +(Set&){...}
Set operator *(Set&){...}
};
main(int argc, char** argv){
SetMl(argv[l]);
Set M2(argv[2]);
SetM3;
МЗ=М1+М2;
Cout<<M3;
МЗ=М1*М2;
Cout<<M3;
}
Контрольные задания
1. Расширить класс Set перегрузкой операций объединения(+) и пересечения(*) над подмножествами заглавных латинских букв.
2. Расширить класс Set перегрузкой операций объединения(+) и пересечения(*) над подмножествами цифр.
3. Расширить класс Set перегрузкой операций объединения(+) и пересечения(*) над подмножествами русских букв.
Рекомендуемая литература
1. Д. Кнут. Искусство программирования для ЭВМ, т.2 Получисленные алгоритмы - М, Мир, 1977 г.
2. П. Лукас. C++ под рукой - Киев, НИПФ "ДиаСофт", 1993 г.