Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.93
Ded_Vasilij
231 / 213 / 15
Регистрация: 01.09.2012
Сообщений: 2,103
#1

Дек символов - C++

15.02.2013, 20:23. Просмотров 1825. Ответов 24
Метки нет (Все метки)

Доброго времени суток всем.
У меня такая проблема: есть задача -
Реализовать класс "Дек символов" (на базе списка).

Реализовать класс "Массив деков". Длина массива определяется во время
инициализации и в дальнейшем не меняется. Массив должен хранить сами деки,
а не указатели на них. Доступ к элементам массива осуществляется с помощью
квадратных скобок.
Начал делать, но поскольку с классами работаю впервые, то не совсем разобрался как это делать.
вот моя реализация:
файл L2.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#pragma once
class L2_elem
{
    char el;
    L2_elem* next;
    L2_elem* prev;
public:
    L2_elem();                                      //занулить указатели
    L2_elem (char c, L2_elem* n,L2_elem* p);        //пприсваивание значений
    char get_el();
    L2_elem* get_n();
    L2_elem* get_p();
};
class L2
{
    L2_elem* head;
    
public:
    L2();                               // инициализация
    ~L2();                              // деструктор
    L2(const L2 &List);                 // копирование
    L2& operator = (const L2& List);    // оператор перегрузки
    char get_el (int i);                // получить элемент
    void put (char el);                 // добавить элемент
    void del();                         // удалить элемент
    void print (L2 List);               // печать
    int size (L2 List);                 // размер списка
};
файл L2.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include "L2.h"
L2_elem :: L2_elem()
{
    L2_elem.next = 0;// error C2143: синтаксическая ошибка: отсутствие ";" перед "."
 
    L2_elem.prev = 0;
}
char L2_elem :: get_el()
{
    return el;
}
 
L2_elem*  L2_elem :: get_n()
{
    return L2_elem.next ;
}
 
 
 
L2 :: L2()
{
    head = new L2_elem;                             // по умолчанию вызывается конструктор без параметров L2_elem
}
Я понимаю, что я сделал чего-то не так, но пока не могу понять чего, ошибка мелкая, из=за нее вся работа встала. Подскажите пожалуйста чего я не так делаю
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.02.2013, 20:23
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Дек символов (C++):

дек - C++
как сделать такую вещь? реализовать и протестировать контейнерный класс динамической структуры данных такой как дек. класс должен иметь...

Очередь и дек С++ - C++
Ребят, помогите пожалуйста сделать небольшую программу, ну просто горит(((. :wall: Разработать программу на С++, для реализации основных...

Полный дек - C++
Добрый день! мучаюсь с задачей - реализовать тип и функции (инициализация,добавление\извлечение элементов с обеих сторон,проверка на...

Шаблонный дек - C++
Задача реализовать шаблонный класс дека, и класс Итератора для навигации по деку. До добавления шаблонов все хорошо работало. Ныне такие...

Простой дек - C++
Помогите решить задачу : Реализуйте структуру данных &quot;дек&quot;. Напишите программу, содержащую описание дека и моделирующую работу дека,...

Дек-шаблон - C++
Доброй ночи. У меня вопрос. Я хочу реализовать дек, а потом на его основе сделать шаблон. В деке могут храниться как числа, так и...

24
ya_noob
_
201 / 145 / 9
Регистрация: 08.10.2011
Сообщений: 432
20.02.2013, 11:36 #16
1. деструктор - это легко: это функция, которая прибирает за объектом перед его удалением. Просто пробегись циклом и удали все узлы списка.
2. конструктор копирования - слегка посложнее: надо создать копию списка на основе уже имеющегося экземпляра. Объявление конструктора копирование такое:
C++
1
L2( L2 &x );
Здесь надо пробежаться циклом по списку x и на основе информации в его узлах сформировать новый список (для добавления узлов в новый список можно воспользоваться уже имеющейся функцией pushTail)
3. оператор присваивания - (в данной ситуации) это комбинация деструктора и конструктора копирования, т.е. сначала удаляешь все узлы из списка, а потом создаешь новый список на основе списка правого операнда.
Объявление такое:
C++
1
L2 &operator=( L2 &x );
1
Ded_Vasilij
231 / 213 / 15
Регистрация: 01.09.2012
Сообщений: 2,103
20.02.2013, 20:33  [ТС] #17
С конструктором копирования и деструктором понятно. а вот для чего нужен оператор присваивания? Хотелось бы знать не только что делать, но и зачем.
0
ya_noob
_
201 / 145 / 9
Регистрация: 08.10.2011
Сообщений: 432
22.02.2013, 11:15 #18
Цитата Сообщение от Ded_Vasilij Посмотреть сообщение
для чего нужен оператор присваивания? Хотелось бы знать не только что делать, но и зачем.
Чтобы делать вот так, например:
C++
1
2
3
4
5
L2 list1;
L2 list2;
 
for ( char c = 'a'; c <= 'z'; ++c ) list1.pushTail( c ); // формируем список list1
list2 = list1;
Здесь мы хотим скопировать содержимое списка list1 в список list2. Как видно, это выполняется в одну строку (list2 = list1; ) с помощью перегруженной операции присваивания. А теперь представь, как бы усложнилось чтение этого кода, если бы вместо одной этой строки ты расписал бы всё определение operator=. Следовательно, перегруженные операторы помогают писать более лаконичный код. Но основным назначением перегрузки операторов является возможность обращаться с пользовательскими типами данных как со встроенными.
0
Ded_Vasilij
231 / 213 / 15
Регистрация: 01.09.2012
Сообщений: 2,103
23.02.2013, 14:33  [ТС] #19
Благодарю, уже разобрался - на лекции объяснили.
У меня теперь другая проблема. написал конструктор копирования и деструктор - по хожу дела очень коряво. При завершении работы пишет "Необработанное исключение в "0x00a020bc" в "task3.exe": 0xC0000005: Нарушение прав доступа при записи "0x00000004"."
Посмотрите пожалуйста, чего я не так опять сделал.
вот код
файл L2.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#pragma once
 
class L2_elem
{
public: 
    char el;
    L2_elem* next;
    L2_elem* prev;
    L2_elem();                                      //занулить указатели
    L2_elem (char c, L2_elem* n,L2_elem* p);        //присваивание значений
    char get_el();
    L2_elem* get_n();
    L2_elem* get_p();
};
class L2 
{
 
    L2_elem* head;                              // голова
    L2_elem* tail;                              // хвост
public:
    L2();                                       // инициализация
    ~L2();                                      // деструктор
    L2(const L2 &List);                     // копирование
    //L2& operator = (const L2& List);          // оператор перегрузки
    bool isEmpty ();
    char popHead ();                            // получить элемент из начала списка
    char popTail ();                            // получить элемент из конца списка
    void pushHead (char c);                     // добавить элемент в начало списка
    void pushTail (char c);                     // добавить элемент в конец списка  
    void printHead ();                      // печать с головы
    void printTail();                   // печать с хвоста
    int size ();                            // размер списка
    void makeEmpty();
};
файл L2.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#include <iostream>
#include "L2.h"
using namespace std;
L2_elem :: L2_elem()
    : prev(0), next(0)
{
    
}
char L2_elem :: get_el()
{
    return el;
}
 
L2_elem*  L2_elem :: get_p()
{
    return prev;
}
 
L2_elem :: L2_elem (char c, L2_elem* n,L2_elem* p)      //присваивание значений
{
    el = c;
    next = n;
    prev = p;
}
//реализация L2
L2 :: L2()
{
    head = 0;                                           // по умолчанию вызывается конструктор без параметров L2_elem
    tail = 0;
}
 
bool L2 :: isEmpty ()
{
    return head == 0;
} 
void L2 :: makeEmpty()
{   
    while (head !=0)
    {
        head = head->next;          
        delete head->prev;
    }
    head->next = 0;
}
 
L2 :: ~L2()
{
    makeEmpty();
}
L2 :: L2 (const L2 &List)
{
    L2_elem* temp = List.head;
    while (temp)
    {
        char c = temp->el;
        temp = temp->next;
        pushHead(c);
    }
}
void L2 :: pushHead (char c)                            // добавить элемент в начало списка
{
    L2_elem* NewEl = new L2_elem(c, head, 0);
    if ( isEmpty() )                                    // если список пуст
    {
        head = NewEl;                                   // делаем новый элемент головой
        tail = head;
    }
    else
    {
        head->prev = NewEl;
        head = NewEl;
    }
}
void L2 :: pushTail (char c)                            // добавить элемент в конец списка  
{
    L2_elem* NewEl = new L2_elem(c,0,tail); 
    if ( isEmpty() )                                    // если список пуст
    {
        tail = NewEl;                                   // делаем новый элемент хвостом
        head = tail;
    }
    else
    {
        tail->next = NewEl;
        tail = NewEl;
    }
}
 
char L2 :: popHead () 
{
    if ( isEmpty() ) return 0;  
    char c = head->el;    
    if ( head->next == 0 )                              // если в списке всего 1 элемент
    {
        delete head;                                    // удаляем его
        head = 0;                                       // и говорим, что список пуст
        tail = 0;
    }
    else 
    {
        head = head->next;                              // сдвигаем tail на предыдущий элемент
        delete  head->prev;                             // и удаляем старый последний элемент
        head->prev = 0;
    }
 
    return c;
}
 
char L2 :: popTail () 
{
    if ( isEmpty() ) return 0; 
 
    char c = tail->el;
    
    if ( tail->prev == 0 )                              // если в списке всего 1 элемент
    {
        delete tail;                                    // удаляем его
        head = 0;                                       // и говорим, что список пуст
        tail = 0;
    }
    else 
    {
        tail = tail->prev;                              // сдвигаем tail на предыдущий элемент
        delete ( tail->next );                          // и удаляем старый последний элемент
        tail->next = 0;
    }
 
    return c;
}
 
void L2 :: printHead()
{
    L2_elem* temp = head;
    
    while (temp)
    {
        cout << temp->el << " ";
        temp = temp->next;
    }
    cout << endl;
}
 
void L2 :: printTail()
{
    L2_elem* temp = tail;
    while (temp)
    {
        cout << temp->el << " ";
        temp = temp->prev;
    }
    cout << endl;
}
 
int L2 :: size()
{
    L2_elem* temp = head;
    int size = 0;
    while (temp)
    {       
        temp = temp->next;
        size++;
    }
    return size;
}
на всякий случай оставил все функции, может еще где косяки есть
0
Kuzia domovenok
1891 / 1746 / 118
Регистрация: 25.03.2012
Сообщений: 5,926
Записей в блоге: 1
23.02.2013, 14:36 #20
Попытка записи по какому-то указателю, по которому не была выделена память.

Добавлено через 2 минуты
Цитата Сообщение от Ded_Vasilij Посмотреть сообщение
head->next = 0;
строка 43.
уже сам head равен NULL
нельзя значит ни к одному его полю обращаться: ни к next ни к pre ни el
0
ya_noob
_
201 / 145 / 9
Регистрация: 08.10.2011
Сообщений: 432
23.02.2013, 19:57 #21
Ошибка №1. Если в цикле ты сделал переход head = head->next и он стал равен 0, то что удалится при вызове delete head->prev?
Цитата Сообщение от Ded_Vasilij Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
void L2 :: makeEmpty()
{
    while (head !=0)
    {
        head = head->next; 
        delete head->prev;
    }
    head->next = 0;
}
Ошибка №2.
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
строка 43.
уже сам head равен NULL
Ошибка №3 (логическая)
Цитата Сообщение от Ded_Vasilij Посмотреть сообщение
C++
1
2
3
4
5
6
L2 :: L2 (const L2 &List)
{
...
        pushHead(c);
....
}
ты скопируешь список задом наперед. Надо pushTail
1
Ded_Vasilij
231 / 213 / 15
Регистрация: 01.09.2012
Сообщений: 2,103
23.02.2013, 21:23  [ТС] #22
Как обычно по мелочи затупил. Внимательнее надо быть.
вот рабочая makeEmpty()

C++
1
2
3
4
5
6
7
8
9
10
11
void L2 :: makeEmpty()
{   
    L2_elem* p = 0;
    while (head !=0)
    {
        p = head;
        head = head->next;          
        delete p;
    }
    head = 0;
}
А по поводу оператора присваивания - по моему надо сперва очистить второй список с помощью makeEmpty, а затем просто скопировать с помощью конструктора копирования.
И все будет в шоколаде. По моему так
0
ya_noob
_
201 / 145 / 9
Регистрация: 08.10.2011
Сообщений: 432
23.02.2013, 22:02 #23
про оператор присваивания я уже писал раньше. вначале очищаешь список, а потом добавляешь в него элементы из другого списка с помощью pushTail

Добавлено через 12 минут
ты не сможешь вызвать конструктор копии как функцию
0
Ded_Vasilij
231 / 213 / 15
Регистрация: 01.09.2012
Сообщений: 2,103
07.03.2013, 18:27  [ТС] #24
вроде бы написал L2, со всеми необходимыми методами, осталось только вставку и удаление элемента после заданного добавить.
Подскажите пожалуйста, что можно оптимизировать в коде, и с какого бока подступиться к деку, точнее говоря, насколько я понял, у дека будут те же методы, что и у L2, но как это правильно организовать?
0
Вложения
Тип файла: rar task 3.rar (4.0 Кб, 5 просмотров)
Ded_Vasilij
231 / 213 / 15
Регистрация: 01.09.2012
Сообщений: 2,103
07.03.2013, 18:43  [ТС] #25
при написании функции
C++
1
AddAfter(int i, char c){}
возникла проблема: мне нужно определить, не вылетает ли i за границы списка, но я не могу получить доступ к функции size(), this.size() тоже ошибку пишет. Подскажите, как обмануть судьбу пожалуйста.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.03.2013, 18:43
Привет! Вот еще темы с ответами:

Простой дек - C++
Всем доброго вечера Столкнулся со следующей проблемой. Есть задание на простой дек: Реализуйте структуру данных &quot;дек&quot;. Напишите...

Вектор, дек, список - C++
Здравствуйте. Помогите пожалуйста разобраться в ошибках, которые возникают при компиляции. Вот они 145 C:\Documents and...

Дек в виде массива - C++
Подскажите как реализовать дек в виде массива.

Дек и удаление элемента - C++
Создать список из целых чисел. Найти минимальный элемент и удалить из списка все элементы, равные минимальному. #include &lt;iostream&gt; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
25
Yandex
Объявления
07.03.2013, 18:43
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru