Объектно-ориентированное программирование - Учебное пособие (А.А. Хусаинов)

Расчетно-графическое задание 2

 

Шаблоны функций и классов

Задание

Написать параметризованную подпрограмму сортировки указанным методом. Отладить ее на целых числах и числах с плавающей точкой.

Определить класс объектов массива, предназначенного для сортировки. Перегрузить для него операцию присваивания и операции сравнения <, <=, ==, >=, >.

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

 

Варианты заданий

Рассмотрим следующие методы сортировки:

   S1. Пирамидальная сортировка.

   S2. Сортировка подсчетом.

   S3. Метод Шелла.

   S4. Быстрая сортировка.

   S5. Метод выбора.

   S6. Метод вставок.

Рассмотрим классы:

   String – строка символов;

   Fraction – рациональная дробь;

   Bits – битовая строка;

   Bcd – строка, состоящая из десятичных цифр, записанных как символы;

   Vector – n-мерный вектор, вектора сортируются в лексикографическом порядке.

 

Комбинируя методы сортировки и классы, получаем варианты заданий:

 

 

S1

S2

S3

S4

S5

S6

String

1

6

11

16

21

26

Fraction

2

7

12

17

22

27

Bits

3

8

13

18

23

28

Bcd

4

9

14

19

24

29

Vector

5

10

15

20

25

30

 

Примеры выполнения РГЗ 2

 

Пример 1

Задание

 

Написать параметризованную подпрограмму сортировки указанным   методом. Отладить ее на целых числах и числах с плавающей точкой.

Определить класс объектов массива, предназначенного для сортировки. Перегрузить для него операцию присваивания и операции сравнения <, <=, ==, >=, >.

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

 

Метод сортировки - метод Шелла, класс - битовая строка.

 

Программа

 

#include <iostream.h>

#include <string.h>

#include <conio.h>

#include <stdlib.h>

#define n 100

 

//класс: Битовая строка

class BinStr

{

private:

   char *s;           //сама строка

   int  length; //указатель на длину

public:

   BinStr();

   BinStr(char *);

   BinStr(const BinStr &);

   ~BinStr();

   int operator> (BinStr &);

   int operator>=(BinStr &);

   int operator< (BinStr &);

   int operator<=(BinStr &);

   int operator==(BinStr &);

   BinStr &operator=(BinStr &Object);//перегрузка оператора присваивания

   friend ostream &operator<<(ostream &, BinStr &);

};

 

BinStr::BinStr()

{

   s=new char[1];

   *s='';

   length=0;

}

BinStr::BinStr(char *st)

{

   length=strlen(st);

   s=new char[(length)+1];

   strcpy (s,st);

}

BinStr::BinStr(const BinStr &s1)

{

   length=strlen(s1.s);

   s=new char[(length)+1];

   strcpy (s,s1.s);

}

BinStr::~BinStr()

{

   delete s;

}

 

int BinStr::operator> (BinStr &Object)

{

   int i;

   //если длина левой строки больше правой

   if(length>Object.length)

   {

      //проверяем, есть ли в старших битах левой

      //строки, которых нет в правой, единицы

      //если есть, то возвращаем 1

      for(i=0;i<length-Object.length;i++)

    if((s[i]-48)==1)

       return 1;

      //если единиц не оказалось, то побитово сравниваем

      //обе строки: оставшуюся часть правой строки со всей левой,

      //до нарушения равновесия

      for(i=0;i<Object.length;i++)

    if((s[i+(length-Object.length)]-48)<(Object.s[i]-48))

       return 0;

    else if((s[i+(length-Object.length)]-48)>(Object.s[i]-48))

       return 1;

      //если строки равны, возвращаем 0

      return 0;

   }

   //далее следует все аналогично для оставшихся двух случаев,

   //когда правая строка длиннее левой и когда длины строк равны

   else if(length<Object.length)

   {

      for(i=0;i<Object.length-length;i++)

    if((Object.s[i]-48)==1)

       return 0;

      for(i=0;i<length;i++)

    if((s[i]-48)<(Object.s[i+Object.length-length]-48))

       return 0;

    else if((s[i]-48)>(Object.s[i+Object.length-length]-48))

       return 1;

      //если строки равны, возвращаем 0

      return 0;

   }

   //когда длины строк равны, просто побитово сравниваем обе строки

   //до нарушения равновесия

   for(i=0;i<length;i++)

      if((s[i]-48)<(Object.s[i]-48))

    return 0;

      else if((s[i]-48)>(Object.s[i]-48))

    return 1;

   //если строки равны, возвращаем 0

   return 0;

}

int BinStr::operator>=(BinStr &Object)

{

   int i;

   //если длина левой строки больше правой

   if(length>Object.length)

   {

      //проверяем, есть ли в старших битах левой

      //строки, которых нет в правой, единицы

      //если есть, то возвращаем 1

      for(i=0;i<length-Object.length;i++)

    if((s[i]-48)==1)

       return 1;

      //если единиц не оказалось, то побитово сравниваем

      //обе строки: оставшуюся часть правой строки со всей левой,

      //до нарушения равновесия

      for(i=0;i<Object.length;i++)

    if((s[i+(length-Object.length)]-48)<(Object.s[i]-48))

       return 0;

    else if((s[i+(length-Object.length)]-48)>(Object.s[i]-48))

       return 1;

      //если строки равны, возвращаем 1

      return 1;

   }

   //далее следует все аналогично для оставшихся двух случаев,

   //когда правая строка длиннее левой и когда длины строк равны

   else if(length<Object.length)

   {

      for(i=0;i<Object.length-length;i++)

    if((Object.s[i]-48)==1)

       return 0;

      for(i=0;i<length;i++)

    if((s[i]-48)<(Object.s[i+Object.length-length]-48))

       return 0;

    else if((s[i]-48)>(Object.s[i+Object.length-length]-48))

       return 1;

      //если строки равны, возвращаем 1

      return 1;

   }

   //когда длины строк равны, просто побитово сравниваем обе строки

   //до нарушения равновесия

   for(i=0;i<length;i++)

      if((s[i]-48)<(Object.s[i]-48))

    return 0;

      else if((s[i]-48)>(Object.s[i]-48))

    return 1;

   //если строки равны, возвращаем 1

   return 1;

}

 

int BinStr::operator< (BinStr &Object)

{

   int i;

   //если длина левой строки больше правой

   if(length>Object.length)

   {

      //проверяем, есть ли в старших битах левой

      //строки, которых нет в правой, единицы

      //если есть, то возвращаем 0

      for(i=0;i<length-Object.length;i++)

    if((s[i]-48)==1)

       return 0;

      //если единиц не оказалось, то побитово сравниваем

      //обе строки: оставшуюся часть правой строки со всей левой,

      //до нарушения равновесия

      for(i=0;i<Object.length;i++)

    if((s[i+(length-Object.length)]-48)<(Object.s[i]-48))

       return 1;

    else if((s[i+(length-Object.length)]-48)>(Object.s[i]-48))

       return 0;

      //если строки равны, возвращаем 0

      return 0;

   }

   //далее следует все аналогично для оставшихся двух случаев,

   //когда правая строка длиннее левой и когда длины строк равны

   else if(length<Object.length)

   {

      for(i=0;i<Object.length-length;i++)

    if((Object.s[i]-48)==1)

       return 1;

      for(i=0;i<length;i++)

    if((s[i]-48)<(Object.s[i+Object.length-length]-48))

       return 1;

    else if((s[i]-48)>(Object.s[i+Object.length-length]-48))

       return 0;

      //если строки равны, возвращаем 0

      return 0;

   }

   //когда длины строк равны, просто побитово сравниваем обе строки

   //до нарушения равновесия

   for(i=0;i<length;i++)

      if((s[i]-48)<(Object.s[i]-48))

    return 1;

      else if((s[i]-48)>(Object.s[i]-48))

    return 0;

   //если строки равны, возвращаем 0

   return 0;

}

 

int BinStr::operator<=(BinStr &Object)

{

   int i;

   //если длина левой строки больше правой

   if(length>Object.length)

   {

      //проверяем, есть ли в старших битах левой

      //строки, которых нет в правой, единицы

      //если есть, то возвращаем 0

      for(i=0;i<length-Object.length;i++)

    if((s[i]-48)==1)

       return 0;

      //если единиц не оказалось, то побитово сравниваем

      //обе строки: оставшуюся часть правой строки со всей левой,

      //до нарушения равновесия

      for(i=0;i<Object.length;i++)

    if((s[i+(length-Object.length)]-48)<(Object.s[i]-48))

       return 1;

    else if((s[i+(length-Object.length)]-48)>(Object.s[i]-48))

       return 0;

      //если строки равны, возвращаем 1

      return 1;

   }

   //далее следует все аналогично для оставшихся двух случаев,

   //когда правая строка длиннее левой и когда длины строк равны

   else if(length<Object.length)

   {

      for(i=0;i<Object.length-length;i++)

    if((Object.s[i]-48)==1)

       return 1;

      for(i=0;i<length;i++)

    if((s[i]-48)<(Object.s[i+Object.length-length]-48))

       return 1;

    else if((s[i]-48)>(Object.s[i+Object.length-length]-48))

       return 0;

      //если строки равны, возвращаем 1

      return 1;

   }

   //когда длины строк равны, просто побитово сравниваем обе строки

   //до нарушения равновесия

   for(i=0;i<length;i++)

      if((s[i]-48)<(Object.s[i]-48))

    return 1;

      else if((s[i]-48)>(Object.s[i]-48))

    return 0;

   //если строки равны, возвращаем 1

   return 1;

}

 

int BinStr::operator==(BinStr &Object)

{

   int i;

   //если длина левой строки больше правой

   if(length>Object.length)

   {

      //проверяем, есть ли в старших битах левой

      //строки, которых нет в правой, единицы

      //если есть, то возвращаем 0

      for(i=0;i<length-Object.length;i++)

    if((s[i]-48)==1)

       return 0;

      //если единиц не оказалось, то побитово сравниваем

      //обе строки: оставшуюся часть правой строки со всей левой,

      //до нарушения равновесия

      for(i=0;i<Object.length;i++)

    if((s[i+(length-Object.length)]-48)!=(Object.s[i]-48))

       return 0;

      //если строки равны, возвращаем 1

      return 1;

   }

   //далее следует все аналогично для оставшихся двух случаев,

   //когда правая строка длиннее левой и когда длины строк равны

   else if(length<Object.length)

   {

      for(i=0;i<Object.length-length;i++)

    if((Object.s[i]-48)==1)

       return 0;

      for(i=0;i<length;i++)

    if((s[i]-48)!=(Object.s[i+Object.length-length]-48))

       return 0;

      //если строки равны, возвращаем 1

      return 1;

   }

   //когда длины строк равны, просто побитово сравниваем обе строки

   //до нарушения равновесия

   for(i=0;i<length;i++)

      if((s[i]-48)!=(Object.s[i]-48))

    return 0;

   //если строки равны, возвращаем 1

   return 1;

}

 

BinStr& BinStr::operator=(BinStr &Object)

{

   length=strlen(Object.s);

   s=new char[(length)+1];

   strcpy (s,Object.s);

   return *this;

}

 

ostream &operator<<(ostream &fo, BinStr &fp)

{

   fo<<fp.s;

   return fo;

}

 

template <class Type>

void shell(Type *x, int n1)

{ int i,j,k,gap;

 Type t;

 int a[5]={9,5,3,2,1};

 for(k=0; k<5; k++)

   { gap=a[k];

    for(i=gap; i<n1; i++)

               { t=x[i];

                for(j=i-gap; t<x[j]&&j>=0; j=j-gap)

                           x[j+gap]=x[j];

                x[j+gap]=t;

               }

   }

}

 

void main()

{

   int i;

   int   mas1[n];

   float mas2[n];

   randomize();

   for (i=0;i<n;i++)

   {

      mas1[i]=random(n);

      mas2[i]=random(n)*0.01;

   }

 

   clrscr();

   cout<<"                       Сортировка методом Шелла "<<endl;

   //сортировка целых чисел

   shell(mas1, n);

   cout<<"Отсортированный массив целых чисел: "<<endl;

   for (i=0;i<n;i++)

      cout<<mas1[i]<<" ";

   //сортировка чисел с плавающей точкой

   shell(mas2, n);

   cout<<endl<<" Отсортированный массив чисел с плавающей точкой: "<<endl;

   for (i=0;i<n;i++)

      cout<<mas2[i]<<" ";

 

BinStr mas3[n]={"1001","1000","1100","1010","1100","1011","0011","1111",

               "000000000001","0110","1110","011001","1111","0011","0110",

               "1011","0101","0011","0010","1111"};

   //сортировка битовых строк

   shell(mas3, n);

   cout<<endl<<endl<<"Отсортированный массив битовых строк:"<<endl;

   for (i=0;i<n;i++)

      cout<<mas3[i]<<" ";

}

 

Результаты работы программы

 

Сортировка методом Шелла

 

Отсортированный массив целых чисел:

 

0 1 1 2 3 4 4 5 6 6 7 9 9 10 10 11 11 11 13 15 16 16 16 17 18 19 19 20 20 21 21

22 22 24 24 24 26 26 26 28 28 33 33 35 37 37 38 38 42 45 45 45 46 46 46 48 53 54

 55 55 55 56 57 62 62 62 64 64 65 65 69 69 70 71 71 71 71 73 74 75 75 75 77 79 8

0 80 80 80 83 86 88 88 90 92 93 95 96 96 98 99

 

Отсортированный массив чисел с плавающей точкой:

 

0 0 0.01 0.02 0.02 0.04 0.07 0.07 0.1 0.11 0.12 0.12 0.13 0.14 0.17 0.17 0.17 0.

19 0.2 0.2 0.2 0.21 0.22 0.22 0.22 0.23 0.23 0.24 0.24 0.27 0.27 0.27 0.28 0.29

0.3 0.31 0.34 0.35 0.35 0.35 0.37 0.37 0.37 0.4 0.43 0.43 0.44 0.44 0.46 0.48 0.

5 0.51 0.52 0.53 0.54 0.55 0.55 0.55 0.56 0.59 0.6 0.61 0.63 0.63 0.67 0.69 0.7

0.71 0.73 0.73 0.74 0.74 0.74 0.76 0.77 0.77 0.78 0.79 0.8 0.81 0.82 0.83 0.86 0

.87 0.87 0.88 0.9 0.9 0.9 0.9 0.92 0.93 0.93 0.94 0.94 0.94 0.94 0.97 0.97 0.98

 

Отсортированный массив битовых строк:

 

000000000001 0010 0011 0011 0011 0101 0110 0110 1000 1001 1010 1011 1011 1100 11

00 1110 1111 1111 1111 011001

 

Пример 2

 

Задание

 

Написать параметризованную подпрограмму сортировки указанным методом. Отладить ее на целых числах и числах с плавающей точкой.   

Определить класс объектов массива, предназначенного для сортировки. Перегрузить для него операцию присваивания и операции сравнения <, <=, ==, >=, >.         

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

 

Метод сортировки - метод вставок, класс – строка символов.

Программа

 

#include <iostream.h>

#include <string.h>

#include <conio.h>

#include <stdlib.h>

 

// Класс - строка символов

class SymStr

   {

   private:

               char *s;                                    // Строка

               int  length;       // Длина строки

   public:

               // Конструкторы

               SymStr()

                           {

                           s=new char[1];

                           *s='';

                           length=0;

                           }

 

               SymStr(char *str)

                           {

                           length = strlen(str);

                           s = new char[length + 1];

                           strcpy (s, str);

                           }

 

               SymStr(const SymStr &str)

                           {

                           length = str.length;

                           s = new char[length + 1];

                           strcpy (s, str.s);

                           }

 

               // Деструктор

               ~SymStr() { delete s; }

 

               // Перегрузка оператора >

    &