Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.59/22: Рейтинг темы: голосов - 22, средняя оценка - 4.59
30 / 24 / 6
Регистрация: 24.11.2020
Сообщений: 214

Создать стек на основе списка структур

14.04.2021, 14:08. Показов 4287. Ответов 31
Метки c++ (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! Задание такое: Создать стек на основе структур (в данном случае на основе односвязного списка), почти что закончила код, но не получается сделать удаление элемента стека, помогите, пожалуйста. И ещё, какие функции можно добавить в программу? Например, сейчас есть добавление элемента в стек, вывод всех элементов на экран и поиск и удаление выбранного элемента (нужна починка). Может можно добавить что-то ещё?
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#include <stdio.h>
#include <iostream>
#include <Windows.h>
 
using namespace std;
 
struct comp { //Структура с именем comp
    char udknum[30];
    char fio[30];
    char bookname[40];
    int year;
    int kolvo;
    comp* next;//Указатель типа comp на следующий элемент
};
 
void s_push(comp** top) {
    comp* q; //Создаем новый указатель q, который приравниваем к вершине стека. По сути это и есть наш новый элемент
    q = new comp(); //выделяем память для нового элемента
    cout << "Введите УДК книги: ";
    cin.getline(q->udknum, 30);
    cout << "Введите ФИО автора книги: ";
    cin.getline(q->fio, 30);
    cout << "Введите название книги: ";
    cin.getline(q->bookname, 40);
    cout << "Введите год издания книги: ";
    cin >> q->year;
    cout << "Введите количество книг: ";
    cin >> q->kolvo;
    cout << endl;
    if (top == NULL) { //Если вершины нет, то есть стек пустой
        *top = q; //вершиной стека будет новый элемент
    }
    else //если стек не пустой
    {
        q->next = *top; //Проводим связь от нового элемента, к вершине. То есть кладем книжку на вершину стопки.
        *top = q; //Пишем, что вершиной теперь является новый элемент
    }
}
 
void s_delete_key(comp** top, char NewUdk[]) {//функция которая принимает вершину top и число которое нужно удалить
    comp* q = *top; //создаем указатель типа comp и приравниваем(ставим) его на вершину стека
    comp* prev = NULL;//создаем указатель на предыдущий элемент, с начала он будет пустым
    while (q != NULL) {//пока указатель q не пустой, мы его будем проверять, если он все же пусть цикл заканчивается
        if (q->udknum == NewUdk) {
            if (q == *top) {//если такой указатель равен вершине, то есть элемент, который нам нужно удалить - вершина
                *top = q->next;//передвигаем вершину на следующий элемент
                free(q);//очищаем ячейку
                q->udknum[30] = NULL; 
                q->fio[30] = NULL; 
                q->year = NULL;
                q->kolvo = NULL; 
                q->next = NULL;
            }
            else//если элемент последний или находится между двумя другими элементами
            {
                prev->next = q->next;//Проводим связь от предыдущего элемента к следующему
                free(q);//очищаем ячейку 
                q->udknum[30] = NULL; 
                q->fio[30] = NULL; 
                q->bookname[40] = NULL;
                q->year = NULL;
                q->kolvo = NULL; 
                q->next = NULL;
            }
        }
        prev = q; //запоминаем текущую ячейку как предыдущую
        q = q->next;//перемещаем указатель q на следующий элемент
    }
}
 
comp* FindPrev(comp* top, char NewUdk[]) //поиск узла
{
    comp* q = nullptr;
    while (top && strcmp(top->udknum, NewUdk) != 0)
    {
        q = top;
        top = top->next;
    }
    return q;
}
 
comp* Find(comp* top, char NewUdk[]) //поиск узла
{
    comp* q = FindPrev(top, NewUdk);
    return q ? q->next : top;
}
 
void s_print(comp* top) { //принимает указатель на вершину стека        
    comp* q = top; //устанавливаем q на вершину
    while (q) { //пока q не пустой (while(q) эквивалентно while(q != NULL))
        cout << "Номер УДК: " << q->udknum << endl;
        cout << "ФИО автора: " << q->fio << endl;
        cout << "Название книги: " << q->bookname << endl;
        cout << "Год издания: " << q->year << endl;
        cout << "Количество книг: " << q->kolvo << endl;
        cout << endl;
        q = q->next;//после того как вывели передвигаем q на следующий элемент(ячейку)
    }
}
 
int Choice()
{
    int answer;
    cout << endl;
    cout << "Главное меню:" << endl;
    cout << "1. Добавить новую книгу в список" << endl;
    cout << "2. Вывести всю информацию о книгах" << endl;
    cout << "3. Найти и удалить книгу из списка" << endl;
    cout << "4. Очистить экран" << endl;
    cout << "5. Выход" << endl;
    cout << endl;
    cout << "Выберите действие: ";
    (cin >> answer).get();
    cout << endl;
    if (answer >= 1 && answer <= 5)
        return answer;
    else
        return 0;
}
 
int main() 
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
 
    comp* top = NULL; //в начале программы у нас нет очереди, соответственно вершины нет, даем ей значение NULL
    //Дальше начинаем добавлять данные
    int ch; char del; int n;
    comp* q = NULL;
    while (1)
    {
        ch = Choice();
 
        if (ch == 1)
        {
                s_push(&top);
        }
        else if (ch == 2)
        {
                s_print(top);
        }
 
        else if (ch == 3)
        {
            char del;
            char udknum[256];
            cout << "Введите номер УДК для поиска: ";
            cin >> udknum;
 
            q = Find(top, udknum);
            if (q)
            {
                cout << "Номер книги: " << q->udknum << endl;
                cout << "ФИО: " << q->fio << endl;
                cout << "Название: " << q->bookname << endl;
                cout << "Год: " << q->year << endl;
                cout << "Количество: " << q->kolvo << endl;
                cout << endl;
                cout << "Вы хотите удалить эту запись? (y, n): ";
                cin >> del;
                if (del == 'y')
                {
                    s_delete_key(&top, udknum);
                }
                cout << endl;
            }
        }
 
        else if (ch == 4)
        {
            system("cls");
        }
 
        else if (ch == 5)
            exit(0);
    }
    system("pause");
    return 0;
}
Добавлено через 2 минуты
Тут ошибка, думаю, но не знаю, как починить
Цитата Сообщение от ANGELin04ka Посмотреть сообщение
q->udknum[30] = NULL;
                q->fio[30] = NULL;
                q->bookname[40] = NULL;
                q->year = NULL;
                q->kolvo = NULL;
                q->next = NULL;
Добавлено через 1 минуту
Если так написать, то ошибку выдаёт, что нельзя изменять левостороннее значение
C++
1
2
3
4
5
6
                q->udknum = NULL;
                q->fio = NULL;
                q->bookname = NULL;
                q->year = NULL;
                q->kolvo = NULL;
                q->next = NULL;
Добавлено через 35 минут
При нажатии на "3", мы вводим номер УДК, поиск работает, программа находит и выводит информацию о найденной книге, спрашивает, удалить ли её, если нажать удалить и вывести после это все элементы стека, то удаление не произошло, он там как был, так и остался

Добавлено через 21 минуту
Вообще, в предупреждении он пишет, что это индексы, но как тогда удалить не индекс, а именно весь элемент стека со всеми полями?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
14.04.2021, 14:08
Ответы с готовыми решениями:

Стек на основе связанного списка C++
Привет:) Мне нужно разработать функции занесения и извлечения данных стека на основе связанного списка!на основе массива уже написала, а...

Стек на основе односвязного списка (доработать код)
Написать класс &quot;стек&quot; (первый пришел, последний ушел) на основе односвязного списка. Реализовать методы Push и Pop. Стек хранит структуру...

Создать динамическую структуру: список, а также очередь и стек на основе списка
Требуется создать список, стек и очередь на основе списка. С условием : всё должно опичываться в классах.

31
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
14.04.2021, 16:10
Лучший ответ Сообщение было отмечено ANGELin04ka как решение

Решение

Цитата Сообщение от ANGELin04ka Посмотреть сообщение
Тут ошибка, думаю, но не знаю, как починить
C++
1
2
3
4
5
6
7
8
9
10
11
{
    prev->next = q->next;//Проводим связь от предыдущего элемента к следующему
    delete q;
    //free(q);//очищаем ячейку 
    //q->udknum[30] = NULL; 
    //q->fio[30] = NULL; 
    //q->bookname[40] = NULL;
    //q->year = NULL;
    //q->kolvo = NULL; 
    //q->next = NULL;
}
1
30 / 24 / 6
Регистрация: 24.11.2020
Сообщений: 214
14.04.2021, 16:13  [ТС]
oleg-m1973, При нажатии 2-ки (выводе всех элементов на экран), всё равно остаётся тот, который удаляем
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
14.04.2021, 16:16
Цитата Сообщение от ANGELin04ka Посмотреть сообщение
oleg-m1973, При нажатии 2-ки (выводе всех элементов на экран), всё равно остаётся тот, который удаляем
Здесь у тебя обычный односвязный список. Ты ж его вроде уже делала.

Добавлено через 1 минуту
Цитата Сообщение от ANGELin04ka Посмотреть сообщение
comp* FindPrev(comp* top, char NewUdk[]) //поиск узла
Почему не используешь эту функцию для удаления?
1
30 / 24 / 6
Регистрация: 24.11.2020
Сообщений: 214
14.04.2021, 16:16  [ТС]
oleg-m1973, Ну, по заданию надо сделать стек на основе прошлого задания (односвязный список), тоже с книгами
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
14.04.2021, 16:18
Цитата Сообщение от ANGELin04ka Посмотреть сообщение
oleg-m1973, Ну, по заданию надо сделать стек на основе прошлого задания (односвязный список), тоже с книгами
Односвязный список это и есть стек. У тебя там вроде было удаление элемента, или нет?
1
30 / 24 / 6
Регистрация: 24.11.2020
Сообщений: 214
14.04.2021, 16:21  [ТС]
oleg-m1973, Было, значит воспользуюсь им, спасибо за помощь

Добавлено через 2 минуты
oleg-m1973, А в стеке же нельзя некоторые функции из односвязного списка использовать? Чем тогда реализация односвязного списка отличается от стека
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
14.04.2021, 16:21
Так и есть. Просто берёшь оттуда всё полностью и готово. Единственно - для стека можно только удалять элементы из головы и добавлять в голову.
1
30 / 24 / 6
Регистрация: 24.11.2020
Сообщений: 214
14.04.2021, 16:23  [ТС]
Написано, что работает по принципу "Последним пришёл - первым ушёл"

Добавлено через 39 секунд
oleg-m1973, Ну, т.е. я просто удалю лишнее из односвязного списка и всё?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
14.04.2021, 16:23
Лучший ответ Сообщение было отмечено ANGELin04ka как решение

Решение

Там понадобятся только AddFirst и PopFront
1
30 / 24 / 6
Регистрация: 24.11.2020
Сообщений: 214
14.04.2021, 16:31  [ТС]
oleg-m1973, Т.е. это уже стек? А для чего PopFront? И можно ли в стеке удалять так, как в односвязном? Например, удалить не голову, а первый снизу элемент, или который по центру? Ну, я имею ввиду, что тут можно сделать это, а в самом стеке так можно делать?
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
165
166
#include <iostream>
#include <Windows.h>
 
using namespace std;
 
struct CBook // структура с инфой о книгах
{
    char udknum[30];
    char fio[30];
    char bookname[30];
    int year;
    int kolvo;
 
    CBook* next; //Ссылка на следующий указатель
}; typedef CBook* PBook; //Тип данных: указатель на узел
 
PBook CreateBook()
{
    PBook NewBook = new CBook; //Указатель на новый узел
    cout << "Введите УДК книги: ";           //
    cin.getline(NewBook->udknum, 30);       //
    cout << "Введите ФИО автора книги: ";  //
    cin.getline(NewBook->fio, 30);          //
    cout << "Введите название книги: ";     //Заполняем
    cin.getline(NewBook->bookname, 30);     //
    cout << "Введите год издания книги: ";    //
    cin >> NewBook->year;                   //
    cout << "Введите количество книг: ";   //
    cin >> NewBook->kolvo;                  //
    NewBook->next = NULL; //Следующего узла нет
    return NewBook; //адрес узла - резвультат функции
}
 
void AddFirst(PBook& Head, PBook NewBook) //добавление узла в начало
{
    NewBook->next = Head;
    Head = NewBook;
}
 
PBook FindPrev(PBook Head, char NewUdk[]) //поиск узла
{
    PBook p = nullptr;
    while (Head && strcmp(Head->udknum, NewUdk) != 0)
    {
        p = Head;
        Head = Head->next;
    }
    return p;
}
 
PBook Find(PBook Head, char NewUdk[]) //поиск узла
{
    PBook p = FindPrev(Head, NewUdk);
    return p ? p->next : Head;
}
 
void DeleteBook(PBook& Head, PBook OldBook) // удаление узла
{
    PBook q = Head;
    if (Head == OldBook)
        Head = OldBook->next; //удаляем первый элемент
    else
    {
        while (q && q->next != OldBook) //ищем элемент
            q = q->next;
        if (q == NULL) //если не нашли, выходим
            return;
        q->next = OldBook->next;
    }
    delete OldBook; //освобождаем память
}
 
PBook PopFront(PBook& Head)
{
    if (!Head)
        return nullptr;
 
    PBook p = Head;
    Head = Head->next;
    return p;
}
 
int Choice()
{
    int answer;
    cout << endl;
    cout << "Главное меню:" << endl;
    cout << "1. Добавить новую книгу в список" << endl;
    cout << "2. Вывести всю информацию о книгах" << endl;
    cout << "3. Найти и удалить книгу из списка" << endl;
    cout << "4. Очистить экран" << endl;
    cout << "5. Выход" << endl;
    cout << endl;
    cout << "Выберите действие: ";
    (cin >> answer).get();
    cout << endl;
    if (answer >= 1 && answer <= 5)
        return answer;
    else
        return 0;
}
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
 
    int ch; char del;
    PBook Head = NULL, p, q = NULL;
 
    while (1)
    {
        ch = Choice();
 
        if (ch == 1)
            AddFirst(Head, CreateBook());
 
        else if (ch == 2)
        {
            for (auto* p = Head; p; p = p->next)
            {
                cout << "Номер книги: " << p->udknum << endl;
                cout << "ФИО: " << p->fio << endl;
                cout << "Название: " << p->bookname << endl;
                cout << "Год: " << p->year << endl;
                cout << "Количество: " << p->kolvo << endl;
                cout << endl;
            }
        }
 
        else if (ch == 3)
        {
            char del;
            char udknum[256];
            cout << "Введите номер УДК для поиска: ";
            cin >> udknum;
 
            q = Find(Head, udknum);
            if (q)
            {
                cout << "Номер книги: " << q->udknum << endl;
                cout << "ФИО: " << q->fio << endl;
                cout << "Название: " << q->bookname << endl;
                cout << "Год: " << q->year << endl;
                cout << "Количество: " << q->kolvo << endl;
                cout << endl;
                cout << "Вы хотите удалить эту запись? (y, n): ";
                cin >> del;
                if (del == 'y')
                {
                    DeleteBook(Head, q);
                }
                cout << endl;
            }
        }
 
        else if (ch == 4)
        {
            system("cls");
        }
 
        else if (ch == 5)
            exit(0);
    }
    return 0;
}
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
14.04.2021, 16:34
Лучший ответ Сообщение было отмечено ANGELin04ka как решение

Решение

Цитата Сообщение от ANGELin04ka Посмотреть сообщение
И можно ли в стеке удалять так, как в односвязном? Например, удалить не голову, а первый снизу элемент, или который по центру?
Нет нельзя. Оставь только две функции и делай только то, что написано в задании
Удаление -

C++
1
2
PBook p = PopFront(Head);
delete p;
1
30 / 24 / 6
Регистрация: 24.11.2020
Сообщений: 214
14.04.2021, 16:39  [ТС]
oleg-m1973, Спасибо, всё работает
0
30 / 24 / 6
Регистрация: 24.11.2020
Сообщений: 214
02.05.2021, 18:49  [ТС]
oleg-m1973, Подскажите, пожалуйста, как правильно удаление с конца сделать? Он у меня несколько сразу удаляет, вместо последнего, это для структуры "дек", добавление в начало и конец есть, удаление с начала тоже, осталось это
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
#include <iostream>
#include <Windows.h>
 
using namespace std;
 
struct CBook
{
    string symbol;
 
    CBook* next, * prev;
};
typedef CBook* PBook;
 
PBook CreateBook()
{
    PBook NewBook = new CBook; //Указатель на новый узел
    cout << "Введите сообщение для шифровки: ";           //
    cin >> NewBook->symbol;       //
    NewBook->next = NULL; //Следующего узла нет
    NewBook->prev = NULL;
    return NewBook; //адрес узла - результат функции
}
 
void AddFirst(PBook& Head, PBook& Tail, PBook NewBook)
{
    NewBook->next = Head;
    NewBook->prev = NULL;
    if (Head)
        Head->prev = NewBook;
    Head = NewBook;
    if (!Tail)
        Tail = Head;
}
 
void AddLast(PBook& Head, PBook& Tail, PBook NewBook)
{
    NewBook->next = NULL;
    NewBook->prev = Head;
    if (Tail)
        Tail->next = NewBook;
    Tail = NewBook;
    if (!Head)
        Head = Tail;
}
 
void Delete(PBook& Head, PBook& Tail, PBook OldBook)
{
    if (Head == OldBook)
    {
        Head = OldBook->next;
        if (Head)
            Head->prev = NULL;
        else
            Tail = NULL;
    }
    else
    {
        OldBook->prev->next = OldBook->next;
        if (OldBook->next)
            OldBook->next->prev = OldBook->prev;
        else
            Tail = NULL;
    }
    delete OldBook;
}
 
PBook PopFront(PBook& Head)
{
    if (!Head)
        return nullptr;
 
    PBook p = Head;
    Head = Head->next;
    return p;
}
 
PBook PopBack(PBook& Head, PBook& Tail)
{
    if (!Head)
        return nullptr;
 
    PBook p = Tail;
    Tail = Tail->prev;
    Head->next = Head->prev;
    return p;
}
 
 
 
 
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
 
    int ch;
    PBook Head = NULL, Tail = NULL, p, q = NULL;
 
    while (1)
    {
        ch = Choice();
 
        if (ch == 1)
        {
            AddFirst(Head, Tail, CreateBook());
        }
        else if (ch == 2)
        {
            AddLast(Head, Tail, CreateBook());
        }
        else if (ch == 3)
        {
            PBook p = PopFront(Head);
            cout << "Первый элемент дека удалён: " << p->symbol<< endl;
            delete p;
        }
 
        else if (ch == 4)
        {
            PBook p = PopBack(Head, Tail);
            cout << "Последний элемент дека удалён: " << p->symbol << endl;
            delete p;
        }
 
        else if (ch == 5)
        {
            for (auto* p = Head; p; p = p->next)
            {
                cout << "Введённые сообщения для шифровки: " << p->symbol << endl;
                cout << endl;
            }
        }
 
        else if (ch == 6)
        {
            empty(Head, Tail);
            cout << endl;
        }
 
        else if (ch == 7)
        {
            system("cls");
        }
 
        else if (ch == 8)
            exit(0);
    }
}
Добавлено через 3 минуты
Ещё пробовала чуть иначе сделать, но тогда при выводе всех элементов, на элементе, который удалился стопается программа, а те, что были до выводит
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
02.05.2021, 18:52
Цитата Сообщение от ANGELin04ka Посмотреть сообщение
oleg-m1973, Подскажите, пожалуйста, как правильно удаление с конца сделать? Он у меня несколько сразу удаляет, вместо последнего, это для структуры "дек", добавление в начало и конец есть, удаление с начала тоже, осталось это
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
PBook PopBack(PBook& Head, PBook& Tail)
{
    if (!Head)
        return nullptr;
 
    PBook p = Tail;
    Tail = Tail->prev;
    if (!Tail)
        Head = nullptr;
    else
        Tail->next = nullptr;
    return p;
}
Добавлено через 46 секунд
Цитата Сообщение от ANGELin04ka Посмотреть сообщение
PBook PopFront(PBook& Head)
Здесь тоже надо учитывать, что в списке может быть только один элемент

Добавлено через 31 секунду
По аналогии с тем, что я показал
1
30 / 24 / 6
Регистрация: 24.11.2020
Сообщений: 214
02.05.2021, 18:57  [ТС]
oleg-m1973, Поняла, спасибо

Добавлено через 3 минуты
oleg-m1973, Всё равно он оставляет только голову при удалении, я ввела 4 элемента, первый в начало и 3 в конец, удалила последний, вывела, а там только 1 остался
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
02.05.2021, 19:41
Цитата Сообщение от ANGELin04ka Посмотреть сообщение
oleg-m1973, Всё равно он оставляет только голову при удалении, я ввела 4 элемента, первый в начало и 3 в конец, удалила последний, вывела, а там только 1 остался
Цитата Сообщение от ANGELin04ka Посмотреть сообщение
void AddLast(PBook& Head, PBook& Tail, PBook NewBook)
{
    NewBook->next = NULL;
    NewBook->prev = Head;
    if (Tail)
Почему у последнего элемента prev это Head? Наверное, должен быть Tail
1
30 / 24 / 6
Регистрация: 24.11.2020
Сообщений: 214
02.05.2021, 23:24  [ТС]
oleg-m1973, Теперь заработало, спасибо

Добавлено через 1 час 6 минут
oleg-m1973, Подскажите ещё, пожалуйста. Вот у меня по заданию, в файле лежит зашифрованное сообщение, нужно с помощью дека расшифровать (известно, что при шифровке каждый символ сообщения заменялся
следующим за ним в деке по часовой стрелке через один). Я нашла алгоритм шифра Цезаря, сделала копию функции добавления сообщения в дек, шифрует и расшифровывает, вроде бы как надо, но расшифровка получается не из файла же делается
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
#include <iostream>
#include <fstream>
#include <sstream>
#include <Windows.h>
 
using namespace std;
 
struct CBook
{
    string symbol;
 
    CBook* next, * prev;
};
typedef CBook* PBook;
 
ofstream fo1, fo2;
ifstream fi1;
 
PBook CreateBook()
{
    PBook NewBook = new CBook; //Указатель на новый узел
    cout << "Элемент дека: ";           //
    cin >> NewBook->symbol;       //
    fo1 << NewBook->symbol << endl;
    NewBook->next = NULL; //Следующего узла нет
    NewBook->prev = NULL;
    return NewBook; //адрес узла - результат функции
}
 
PBook CreateBook2()
{
    fo1.open("message.txt");
    fo2.open("remessage.txt");
    PBook NewBook = new CBook; //Указатель на новый узел
    cout << "Введите сообщение для шифровки: ";           //
    cin >> NewBook->symbol;       //
    fo1 << NewBook->symbol << endl;
 
 
    int step = 2;
    for (int i = 0; i < NewBook->symbol.size(); i++)
    {
            NewBook->symbol[i] = (NewBook->symbol[i] - 'а' + step) % 32 + 'а';
    }
    cout << "Зашифрованное слово: " << NewBook->symbol << endl;
    fo2 << NewBook->symbol << endl;
 
 
    NewBook->next = NULL; //Следующего узла нет
    NewBook->prev = NULL;
    fo1.close();
    fo2.close();
 
 
    fi1.open("remessage.txt");
    fi1 >> NewBook->symbol;
    for (int i = 0; i < NewBook->symbol.size(); i++)
    {
        NewBook->symbol[i] = (NewBook->symbol[i] - 'а' - 2) % 32 + 'а';
    }
    cout << "Расшифрованное слово: " << NewBook->symbol;
    cout << endl;
    fi1.close();
    return NewBook; //адрес узла - результат функции
}
 
 
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
 
    int ch;
    PBook Head = NULL, Tail = NULL, p, q = NULL;
 
    while (1)
    {
        ch = Choice();
 
        if (ch == 1)
        {
            AddFirst(Head, Tail, CreateBook());
        }
        else if (ch == 2)
        {
            AddLast(Head, Tail, CreateBook());
        }
        else if (ch == 3)
        {
            PBook p = PopFront(Head, Tail);
            cout << "Первый элемент дека удалён: " << p->symbol<< endl;
            delete p;
        }
 
        else if (ch == 4)
        {
            PBook p = PopBack(Head, Tail);
            cout << "Последний элемент дека удалён: " << p->symbol << endl;
            delete p;
        }
 
        else if (ch == 5)
        {
            for (auto* p = Head; p; p = p->next)
            {
                cout << "Введённые сообщения для шифровки: " << p->symbol << endl;
                cout << endl;
            }
        }
 
        else if (ch == 6)
        {
            empty(Head, Tail);
            cout << endl;
        }
 
        else if (ch == 7)
        {
            AddFirst(Head, Tail, CreateBook2());
        }
 
        else if (ch == 8)
        {
            system("cls");
        }
 
        else if (ch == 9)
            exit(0);
    }
}
Добавлено через 2 минуты
oleg-m1973, Я правильно понимаю, что нужно как-то это делать через fi1 >> ? Если я просто запущу программу и не буду ничего в ней делать, сразу приступлю к расшифровке (в файле уже будет зашифрованное слово), то как его так считать можно, чтобы расшифровать

Добавлено через 51 секунду
Сейчас тут обе соединены функции, но хотелось бы разделить их на разные кнопки

Добавлено через 9 минут
oleg-m1973, Вроде, сделала, спасибо большое

Добавлено через 2 часа 18 минут
oleg-m1973, А как сделать замену элементов через 1 для шифровки и дешифровки? Я чуть переделала, теперь я ввожу, например, 5 символов: г, р, у, ш, а (груша), из этих 5 символов происходит шифровка через 1 по кругу -> ушагр
нашла такой алгоритм, но как к своему коду это прибабахать не понимаю
C++
1
2
3
4
5
6
7
8
9
10
11
12
void f(char letter){
        for (int i = 0; i < N; i++){
            if (field[i] == letter){
                if (i == 0)
                    cout << field[N - 2];
                if (i == 1)
                    cout << field[N - 1];
                if ((i != 0) && (i != 1))
                    cout << field[i - 2];
            }
        }
    }
Добавлено через 1 минуту
Вот переделанный немного код:
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
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <Windows.h>
 
using namespace std;
 
struct CBook
{
    char symbol;
 
    CBook* next, * prev;
};
typedef CBook* PBook;
 
ofstream fo1, fo2;
ifstream fi1;
string m;
 
PBook CreateBook()
{
    PBook NewBook = new CBook; //Указатель на новый узел
    cin >> NewBook->symbol;       //
    fo1 << NewBook->symbol << endl;
    NewBook->next = NULL; //Следующего узла нет
    NewBook->prev = NULL;
    return NewBook; //адрес узла - результат функции
}
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
 
    int ch; int symb;
    PBook Head = NULL, Tail = NULL, p, q = NULL;
 
    while (1)
    {
        ch = Choice();
 
        if (ch == 1)
        {
            fo1.open("message.txt");
            cout << "Введите количество символов: ";
            cin >> symb;
            cout << endl;
            for (int i = 0; i < symb; i++)
            {
                cout << "Введите " << i + 1 << " символ: ";
                AddFirst(Head, Tail, CreateBook());
            }
            fo1.close();
        }
        else if (ch == 2)
        {
            fo1.open("message.txt");
            cout << "Введите количество символов: ";
            cin >> symb;
            cout << endl;
            for (int i = 0; i < symb; i++)
            {
                cout << "Введите " << i + 1 << " символ: ";
                AddLast(Head, Tail, CreateBook());
            }
            fo1.close();
        }
        else if (ch == 3)
        {
            PBook p = PopFront(Head, Tail);
            cout << "Первый элемент дека удалён: " << p->symbol<< endl;
            delete p;
        }
 
        else if (ch == 4)
        {
            PBook p = PopBack(Head, Tail);
            cout << "Последний элемент дека удалён: " << p->symbol << endl;
            delete p;
        }
 
        else if (ch == 5)
        {
            for (auto* p = Head; p; p = p->next)
            {
                cout << "Введённые сообщения для шифровки: " << p->symbol;
                cout << endl;
            }
        }
 
        else if (ch == 6)
        {
            empty(Head, Tail);
            cout << endl;
        }
 
        else if (ch == 7)
        {
            AddFirst(Head, Tail, CreateBook());
        }
 
        else if (ch == 8)
        {
            rashifr();
        }
 
        else if (ch == 9)
        {
            system("cls");
        }
 
        else if (ch == 10)
            exit(0);
    }
}
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
02.05.2021, 23:42
Цитата Сообщение от ANGELin04ka Посмотреть сообщение
Вот переделанный немного код:
Я что-то уже плохо соображаю сегодня, завтра посмотрю
1
30 / 24 / 6
Регистрация: 24.11.2020
Сообщений: 214
03.05.2021, 00:05  [ТС]
oleg-m1973, Хорошо, спасибо большое, я на сегодня тоже всё
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
03.05.2021, 00:05
Помогаю со студенческими работами здесь

Создать шаблонный класс - упорядоченный стек на основе связного списка в динамической памяти
Создать шаблонный класс - упорядоченный стек на основе связного списка в динамической памяти. Тип элементов стека определяется параметром...

Стек на основе списка
Помогите организовать стек объектов Person на основе списка с функциями добавления , удаления и изменения элемента class Person {...

Стек на основе списка
Всем привет, нужна ваша помощь в решении следующей задачи: Из элементов двух стеков, хранящих слова, собрать новый стек со словами...

Стек на основе связного списка
#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; const int FALSE = 0; const int TRUE = 1; struct Node { int value; struct...

Стек на основе односвязного списка
Ребят, помогите пожалуйста! Ошибка в функции push. Только я не знаю как ее исправить. Я в отчаянии stack.h typedef struct GRAD { ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru