Ассоциативный массив с возможностью хранения данных произвольных типов (хэш-массив)

  • Вид работы:
    Практическое задание
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    214,94 Кб
  • Опубликовано:
    2012-12-13
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Ассоциативный массив с возможностью хранения данных произвольных типов (хэш-массив)

Содержание

1.       Анализ задания

.        Разработка библиотеки классов

.1       Диаграмма классов

.2       Выбор языка программирования

.3       Реализация классов

.        Разработка тестового приложения

.1 Методика тестирования

.2 Структура тестового приложения

.        Результаты тестирования

Список литературы

Приложение

1. Анализ задания

Ассоциативный массив - абстрактный тип данных <#"587300.files/image001.gif">

Таблица

Объект класса hashmas

Объект класса element

- массив структуры - массив статусов - длина массива - количество элементов в массиве - хэш функция() - увеличение размера массива() - поиск элемента()

- ид типа данных - данные (объединение)

+ добавление() + удаление() + оператор <<() + оператор >>() + оператор []()

+ конструкторы() + оператор =() (для разных типов данных) + оператор <<() + оператор >>() + операторы преобразования типов


На данной диаграмме показан класс Element и Hashmas

.2 Выбор языка программирования

Сравнение C++ с Delphi:, другой инструмент быстрой разработки от Borland, сочетает формы с использованием собственного языка, основанного на языке Pascal. Delphi достиг наивысшей популярности перед появлением VB6, будучи единственным простым языком для создания компонентов СОМ и элементов управления Active X, который могли бы использовать программисты, не знающие С++.

Основанный на использовании пар BEGIN … END для разделения блоков кода, синтаксис Delphi является более громоздким и прямолинейным, чем синтаксис С++.

Сравнение С++ с Java:

Очевидно, что Java оказал сильное влияние на С++. Кто-то однажды назвал С++ - как “Cava”. Андерс Хелзберг (Anders Hejlsberg), лидер группы разработчиков С++, возглавлял также разработку J++, теперь уже не существующего компилятора Java от Microsoft. Синтаксисы Java и С++ похожи. Даже структура библиотеки Java и базовых классов .NET практически одинакова. Разумеется, оба языка используют байт-код.В настоящее время Java имеет сильное преимущество перед С++ - платформенную независимость. Поскольку существуют реализации среды исполнения Java для большинства вычислительных платформ, один и тот же байт-код Java может теоретически выполняться на любой из них. Это то, чего пока не могут достичь программы .NET.

С++ имеет три небольших преимущества перед Java:

.        Синтаксис С++ немного мощнее, чем Java, так как С++ поддерживает перегрузку операторов и безопасные по типу перечисления. В случае необходимости можно использовать в коде С++ указатели и другие “незаконные” идиомы, размещая код внутри “небезопасных” блоков.

.        С++ совместим с кодом, написанным на других языках .NET. Это означает, что ИТ-отдел не обязан использовать только лишь С++ для своих разработок. По этой причине С++ может рассматриваться как более дешевая альтернатива Java.

.        Базовые классы .NET предоставляют С++ унифицированный, стандартизированный источник повсеместно требуемой функциональности, такой как XML, работа с сетью и графикой. Для доступа к аналогичным средствам программисты Java нередко вынуждены использовать множество различных источников.

Сравнение С++ с JavaScript:

Как известно, JavaScript не имеет ничего общего с Java. JavaScript - язык сценариев, применяемый на стороне клиента для оживления web-страниц. Присвоение ему названия JavaScript было бесстыдной маркетинговой политикой, направленной на получение прибыли от успеха Java. Во времена, когда Java в основном использовался для создания апплетов, JavaScript и Java иногда преследовали схожие цели.С++ похож на JavaScript тем. что оба языка наследуют С-подобный синтаксис. С++, однако, не строго интерпретируется, а компилируется в байт-код, который кэшируется и не может быть использован в качестве языка сценариев для web- браузера (по крайней мере, сейчас). В то время как JavaScript основное свое внимание уделяет откликам на события web-браузера, С++ сосредотачивается на создании HTML и получении данных, которые посылает web-браузер.

Как будет показано при обсуждении WebControls, JavaScript и С++ могут использоваться совместно для достижения большего эффекта. В Интернет - приложении код на С++ может определять, какой тип браузера применяется на стороне клиента, и посылать ему фрагмент кода на JavaScript, предназначенный для этого браузера. Разумеется, можно писать страницы ASP.NET с использованием JavaScript (JScript) точно так же, как это делается в ASP-страницах.

2.3 Реализация классов

Класс Element

class element

{:elem_id; //0-пусто 1-int 2-float 3-double 4-char 5-char*data;:

//различные конструкторы(void) {elem_id=0;}(int value)

{_id=1;.eint=value;

}(float value)

{_id=2;.efloat=value;

}(double value)

{_id=3;.edouble=value;

}(char value)

{_id=4;.echar=value;

}(char* value)

{_id=5;

data.estring=value;

}

//перегруженные операторы = для каждого типа данных

const element& operator = (int& value)

{>elem_id=1;>data.eint=value;*this;

}element& operator = (float& value)

{>elem_id=2;>data.efloat=value;*this;

}element& operator = (double& value)

{>elem_id=3;>data.edouble=value;*this;

}element& operator = (char& value)

{>elem_id=4;>data.echar=value;*this;

}element& operator = (char*& value)

{>elem_id=5;>data.estring=value;

return *this;

}

//оператор вывода на экран

friend ostream& operator <<(ostream& os, element& e)

{(e.elem_id)

{1:<<e.data.eint;;2:<<e.data.efloat;;3:<<e.data.edouble;;4:<<e.data.echar;;5:<<e.data.estring;

break;

}os;

}

//перегруженные операторы приведения типов

operator int () throw (char*)

{(elem_id==1) return data.eint;throw ("error");

}float () throw (char*)

{(elem_id==2) return data.efloat;throw ("error");

}double () throw (char*)

{(elem_id==3) return data.edouble;throw ("error");

}char () throw (char*)

{(elem_id==4) return data.echar;throw ("error");

}char* () throw (char*)

{(elem_id==5) return data.estring;

else throw ("error");

}

//перегруженные операторы ввода данных

friend istream& operator >>(istream& is, element& e)

{.elem_id=0;s1[255], *s2;>>s1;(strlen(s1)==1)

{.elem_id=4;.data.echar=s1[0];

}(strcmp(TypeToStr<double>(StrToType<double>(s1)),s1)==0)

{.elem_id=3;.data.edouble=StrToType<double>(s1);

}(strcmp(TypeToStr<float>(StrToType<float>(s1)),s1)==0)

{.elem_id=2;.data.efloat=StrToType<float>(s1);

}(strcmp(TypeToStr<int>(StrToType<int>(s1)),s1)==0)

{.elem_id=1;.data.eint=StrToType<int>(s1);

}(e.elem_id==0)

{.elem_id=5;.data.estring=new char[strlen(s1)+1];(e.data.estring,s1);

}is;

}

};

Класс Hashmas

class hashmas

{:**mas; //массив*deleted; //массив статуса элемента (удален или нет)count; //длина массиваkol; //количество элементов в массивеhash2(char* s, int n) //хэш функции для вычисления индекса

{(n==0) return 0;(127*hash2(s,n-1)+s[n-1])%count;

}hash1(char* s,int i=0)

{(hash2(s,strlen(s))+3*i+5*i*i)%count;

}resize(); //увеличение размера массива в два раза при заполнении 50%seek(char *key); //поиск элемента по ключу

public:(int k=8)

{=new elem1*[k];=new bool[k];=k;=0;(int i=0;i<count;i++)

{[i]=new elem1;[i]->key=NULL;[i]=false;

}

} //конструкторadd (elem1 e); //добавление элемента

bool del(char *key); //удаление элемента по ключу* operator [](char *key) //перегруженный оператор [] в скобках указывается key возвращается data

{mas[this->seek(key)]->data;

}ostream& operator <<(ostream& os, hashmas& h) //оператор вывода массива на экран

{(int i=0;i<h.count;i++)

{((h.mas[i]->key!=NULL)&(h.deleted[i]==false))<<"key: "<<h.mas[i]->key<<" data: "<<*(h.mas[i]->data)<<"\n";

}os;

}istream& operator >>(istream& is, hashmas& h) //ввод элемента массива для добавления

{e;*s=new char[256];* k=new element;b=false;

{<<"Input key: ";>>s;.key=new char[strlen(s)];(e.key,s);<<"Input data: ";>>*k;.data=k;=h.add(e);(b==false) cout<<"This key already used\n";(b==false);is;

Все имена идентификаторов приведены и описаны в строгом соответствии с диаграммой класса пункта 2.1.

3. Разработка тестового приложения

ассоциативный массив тестовый программирование

3.1 Методика тестирования

Методика тестирования заключается в разработке тестового C# приложения.

Необходимо на уровне кода:

1)      Создать экземпляр класса.

)        Наполнить набор студентов элементами с помощью конструктора

)        Протестировать процедуру вывода набора на экран.

)        Протестировать процедуру поиска информации в наборе по дате.

.2 Структура тестового приложения

Система классов реализована на языке C++ и состоит из двух классов и структуры.

Интерфейс класса hashmas

Свойство mas - массив структуры с данными.

Свойство deleted - массив статусов элементов.

Свойство count - размер массива.

Свойство kol - количество элементов в массиве.

Метод hash1 - первая хэш функция.

Метод hash2 - вторая хэш функция.

Метод resize - увеличение размера массива.

Метод seek - поиск элемента по ключу.

Метод operator << - перегруженный оператор вывода массива на экран.

Метод operator >> - перегруженный оператор ввода элемента массива с клавиатуры и его добавление в массив.

Метод add - добавление элемента.

Метод del - удаление элемента.

Метод operator [] - перегруженный оператор [], доступ к элементу массива с заданным ключом.

Структура elem

Поле key - ключ.

Поле data - сопутствующие данные.

Интерфейс класса element

Свойство elem_id - ид типа данных.

Свойство data - данные.

Метод operator = - перегруженный оператор =.

Метод operator << - перегруженный оператор вывода.

Метод operator >> - перегруженный оператор ввода.

Метод operator int() float() double() char() char*() - операторы приведения типов.

Объединение elem

Поле eint - данные типа int.

Поле efloat - данные типа float.

Поле edouble - данные типа double.

Поле echar - данные типа char.

Поле estring - данные типа char*.

4. Результаты тестирования

На рисунке приведен результат работы приложения:

Тестовое приложение разработано на языке C++ консольное приложение.

Программа в цикле запрашивает у пользователя несколько элементов. Добавляет еще один элемент. Выводит данные с определенным ключом. Удаляет элемент с заданным ключом. Программа повторно заносит элемент с удаленным ключом. Выводит массив на экран.


Список литературы

1.       Самоучитель С++, Крупник А.Б., 2005, Издательство: Питер

.        Технологии программирования С++, Давыдов В.Г.,2005. , Издательство: "БХВ-Петербург"

.        Язык программирования С++. Леции и упражнения. Стивен Прата,2003, Издательство: ДиаСофт, Sams

.        Отладка с С++. Руководство для разработчиков. К.Х. Паппас. У.Х. Мюррей, 2009, Издательство: Бином, McGraw-Hill Companies

.        С++. Структурное программирование. Практикум . Павловская Т. А. , ЩупакЮ.А.,2003,Издательство:Питер

Приложение. Система классов

1.       // hash-mas.cpp: определяет точку входа для консольного приложения.

.        #include "stdafx.h"

.        #include "conio.h"

.        #include "string.h"

.        #include <iostream>

.        #include "generalized.cpp"

.        using namespace std;

.        struct elem1 //структура хранит ключ и сопутствующие данные

.        {

.        char *key; //ключ

.        element *data; //данные

.        };

.        class hashmas

.        {

.        private:

.        elem1 **mas; //массив

.        bool *deleted; //массив статуса элемента (удален или нет)

.        int count; //длина массива

.        int kol; //количество элементов в массиве

.        int hash2(char* s, int n) //хэш функции для вычисления индекса

.        {

.        if (n==0) return 0;

.        else

24.     return (127*hash2(s,n-1)+s[n-1])%count;

25.     }

26.     int hash1(char* s,int i=0)

27.     {

28.     return (hash2(s,strlen(s))+3*i+5*i*i)%count;

29.     }

.        void resize(); //увеличение размера массива в два раза при заполнении 50%

.        int seek(char *key); //поиск элемента по ключу

.        public:

.        hashmas(int k=8)

.        {

.        mas=new elem1*[k];

.        deleted=new bool[k];

.        count=k;

.        kol=0;

39.     for (int i=0;i<count;i++)

40.     {

.        mas[i]=new elem1;

.        mas[i]->key=NULL;

.        deleted[i]=false;

.        }

.        } //конструктор

.        bool add (elem1 e); //добавление элемента

.        bool del(char *key); //удаление элемента по ключу

.        element* operator [](char *key) //перегруженный оператор [] в скобках указывается key возвращается data

.        {

50.     return mas[this->seek(key)]->data;

51.     }

.        friend ostream& operator <<(ostream& os, hashmas& h) //оператор вывода массива на экран

.        {

54.     for (int i=0;i<h.count;i++)

55.     {

56.     if ((h.mas[i]->key!=NULL)&(h.deleted[i]==false))

.        os<<"key: "<<h.mas[i]->key<<" data: "<<*(h.mas[i]->data)<<"\n";

58.     }

.        return os;

.        }

61.     friend istream& operator >>(istream& is, hashmas& h) //ввод элемента массива для добавления

62.     {

.        elem1 e;

.        char *s=new char[256];

.        element* k=new element;

.        bool b=false;

.        do

.        {

.        cout<<"Input key: ";

.        cin>>s;

71.     e.key=new char[strlen(s)];

72.     strcpy(e.key,s);

.        cout<<"Input data: ";

.        cin>>*k;

.        e.data=k;

.        b=h.add(e);

77.     if (b==false) cout<<"This key already used\n";

78.     }

.        while (b==false);

.        return is;

.        }

.        };

83.     bool hashmas::add(elem1 e)

84.     {

.        int k=0,i=0;

.        do

.        {

88.     k=hash1(e.key,i);

89.     i++;

.        }

91.     while ((mas[k]->key!=NULL)&(deleted[k]==false)&&(strcmp(mas[k]->key,e.key)!=0));

.        if (mas[k]->key==NULL)

93.     {

94.     mas[k]->key=e.key;

.        mas[k]->data=e.data;

96.     deleted[k]=false;

.        kol++;

98.     if (kol*2==count) this->resize();

99.     return true;

.        }

.        else

102.   if ((strcmp(mas[k]->key,e.key)==0)&(deleted[k]==false)) return false;

103.   else

.        {

105.   mas[k]->key=e.key;

.        mas[k]->data=e.data;

107.   deleted[k]=false;

.        kol++;

109.   if (kol*2==count) this->resize();

110.   return true;

.        }

.        }

113.   int hashmas::seek(char *key)

114.   {

.        int k=0,i=0;

.        do

.        {

.        k=hash1(key,i);

.        i++;

.        }

121.   while ((mas[k]->key!=NULL)&(deleted[k]==false)&&(strcmp(mas[k]->key,key)!=0));

.        if ((mas[k]->key!=NULL)&(deleted[k]==false)&&(strcmp(mas[k]->key,key)==0)) return k; else return -1;

123.   }

.        void hashmas::resize()

.        {

.        hashmas a(count*2);

127.   for (int i=0;i<count;i++)

.        if ((mas[i]->key!=NULL)&(deleted[i]==false))

129.   a.add(*mas[i]);

.        mas=a.mas;

.        count=a.count;

.        kol=a.kol;

.        deleted=a.deleted;

.        }

135.   bool hashmas::del(char *key)

136.   {

137.   int k=this->seek(key);

138.   if (k>-1)

.        {

.        deleted[k]=true;

.        return true;

.        kol--;

.        }

.        else return false;

.        }

146.   int _tmain(int argc, _TCHAR* argv[])

147.   {

.        hashmas a;

.        for (int i=0; i<3; i++)

.        cin>>a;

.        elem1 e;

.        e.key="key";

153.   e.data=new element("data\n");

154.   a.add(e);

.        cout<<a;

.        cout<<a["key"];

.        a.del("key");

158.   cout<<"after delete element with key=key\n";

159.   cout<<a;

160.   cout<<"after add element with key=key\n";

161.   a.add(e);

.        cout<<a;

.        _getch();

.        return 0;

.        }

.        // generalized.cpp: определяет точку входа для консольного приложения.

.        #include "stdafx.h"

.        #include "conio.h"

.        #include "stdio.h"

.        #include <iostream>

.        #include <sstream>

.        using namespace std;

.        //функция преобразования строки в любой тип Т

174.   template <typename T, typename U>

.        T StrToType(const U &rhs)

176.   {

.        T res;

.        ss>>res;

.        return res;

.        }

.        //функция преобразования любого типа Т в строку

.        template <typename T>

184.   char* TypeToStr(const T &rhs)

185.   {

.        std::stringstream ss;

.        ss<<rhs;

188.   std::string s=ss.str();

.        char *s1=new char[s.size()+1];

.        strcpy(s1,s.c_str());

191.   return s1;

.        }

.        //объединение

.        union elem

.        {

.        int eint;

.        float efloat;

.        double edouble;

.        char echar;

.        char* estring;

.        };

.        class element

.        {

.        private:

205.   int elem_id; //0-пусто 1-int 2-float 3-double 4-char 5-char*

206.   elem data;

.        public:

.        //различные конструкторы

.        element(void) {elem_id=0;}

.        element(int value)

.        {

.        elem_id=1;

.        data.eint=value;

.        }

.        element(float value)

.        {

.        elem_id=2;

.        data.efloat=value;

.        }

.        element(double value)

.        {

.        elem_id=3;

.        data.edouble=value;

.        }

.        element(char value)

.        {

.        elem_id=4;

.        data.echar=value;

.        }

.        element(char* value)

.        {

.        elem_id=5;

.        data.estring=value;

.        }

.        //перегруженные операторы = для каждого типа данных

236.   const element& operator = (int& value)

237.   {

.        this->elem_id=1;

.        this->data.eint=value;

.        return *this;

.        }

242.   const element& operator = (float& value)

243.   {

.        this->elem_id=2;

.        this->data.efloat=value;

.        return *this;

.        }

248.   const element& operator = (double& value)

249.   {

.        this->elem_id=3;

.        this->data.edouble=value;

.        return *this;

.        }

254.   const element& operator = (char& value)

255.   {

.        this->elem_id=4;

.        this->data.echar=value;

.        return *this;

.        }

260.   const element& operator = (char*& value)

261.   {

.        this->elem_id=5;

.        this->data.estring=value;

.        return *this;

.        }

.        //оператор вывода на экран

267.   friend ostream& operator <<(ostream& os, element& e)

268.   {

.        switch (e.elem_id)

.        {

.        case 1:

.        os<<e.data.eint;

.        break;

.        case 2:

.        os<<e.data.efloat;

.        break;

.        case 3:

.        os<<e.data.edouble;

.        break;

.        case 4:

.        os<<e.data.echar;

.        break;

.        case 5:

.        os<<e.data.estring;

.        break;

.        }

.        return os;

.        }

.        //перегруженные операторы приведения типов

.        operator int () throw (char*)

.        {

292.   if (elem_id==1) return data.eint;

293.   else throw ("error");

.        }

.        operator float () throw (char*)

.        {

297.   if (elem_id==2) return data.efloat;

298.   else throw ("error");

.        }

.        operator double () throw (char*)

.        {

302.   if (elem_id==3) return data.edouble;

303.   else throw ("error");

.        }

.        operator char () throw (char*)

.        {

307.   if (elem_id==4) return data.echar;

308.   else throw ("error");

.        }

.        operator char* () throw (char*)

.        {

312.   if (elem_id==5) return data.estring;

313.   else throw ("error");

.        }

.        //перегруженные операторы ввода данных

316.   friend istream& operator >>(istream& is, element& e)

317.   {

.        e.elem_id=0;

.        char s1[255], *s2;

.        cin>>s1;

.        if (strlen(s1)==1)

.        {

.        e.elem_id=4;

.        e.data.echar=s1[0];

.        }

326.   if (strcmp(TypeToStr<double>(StrToType<double>(s1)),s1)==0)

327.   {

.        e.elem_id=3;

329.   e.data.edouble=StrToType<double>(s1);

330.   }

331.   if (strcmp(TypeToStr<float>(StrToType<float>(s1)),s1)==0)

332.   {

.        e.elem_id=2;

334.   e.data.efloat=StrToType<float>(s1);

335.   }

336.   if (strcmp(TypeToStr<int>(StrToType<int>(s1)),s1)==0)

337.   {

.        e.elem_id=1;

339.   e.data.eint=StrToType<int>(s1);

340.   }

.        if (e.elem_id==0)

.        {

.        e.elem_id=5;

344.   e.data.estring=new char[strlen(s1)+1];

.        strcpy(e.data.estring,s1);

346.   }

.        return is;

.        }

Похожие работы на - Ассоциативный массив с возможностью хранения данных произвольных типов (хэш-массив)

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!