Всем привет. Мое решение этой задачи(код работает). Посмотрите пожалуйста, я уверен что много циклов напихал и это
не рациональное решение, как вообще возможно оптимизировать данный код?? или он рациональный все таки?
Посмотрите пожалуйста опытным глазом, хотелось бы посмотреть, что тут можно улучшить.
Задан исходный текст на русском языке.
Длина текста — не более NL строк, длина строки — не более NS символов,
длина слова — не более NW символов.
Исходный текст должен заканчиваться точкой ('!', '?').
После обработки исходного текста полученные слова хранить в однонаправленном линейном не кольцевом списке.
В полученном линейном списке найти слова, состоящие только из прописных букв.
В файл результатов напечатать исходный текст (эхо-печать), состояние сформированного линейного списка и найденные слова.
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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
| #pragma once
#ifndef QUEUE_H_
#define QUEUE_H_
#include <string>
using namespace std;
template<typename T>
class List
{
public:
List();
~List();
void pop_front(); // удаление первого элемента в списке
void push_back(T data); // добавление элемента в конец списка
void clear(); // очистить список
void Sizik() { Size++; }
int GetSize() { return Size; } // получить количество елементов в списке
T & operator[](const int index);// перегруженный оператор []
int ss() { return Size; }
private:
template<typename T>
class Node
{
public:
Node * pNext;
T data;
Node(T data = T(), Node *pNext = nullptr)
{
this->data = data;
this->pNext = pNext;
}
};
int Size;
Node<T> *head; // Указатель на первый элемент списка
};
////////////////////////////////////////////////////////////////////////конструктор/деструктор
template<typename T> // конструктор по умолчанию списка
List<T>::List()
{
Size = 0;
head = nullptr;
}
template<typename T> // деструктор по умолчанию списка
List<T>::~List() { clear(); }
template<typename T>
void List<T>::clear()
{
while (Size)
{
pop_front();
}
}
template<typename T> // Первый метод удаляет первый элемент в списке
void List<T>::pop_front()
{
Node<T> *temp = head;// указатель на первый элемент head присваивается временному укз.
head = head->pNext; // укз head перекидывается на след. элемент
delete temp; // удаляется из временного указателя первый элемент списка
Size--; // размер списка декремент
}
////////////////////////////////////////////////////////////////////////конструктор/деструктор
template<typename T>
void List<T>::push_back(T data) // передали элемент в data
{
if (head == nullptr) // если указатель на первый элемент null то
{
head = new Node<T>(data); // new Node<T> выделило область памяти которую сразу
} // инициализировало взятой в скубки data
else
{
Node<T> *current = this->head; // присвоили времен. укз адрс првг элмнта
while (current->pNext != nullptr) // пока в укз первг элм укз на слд не равн null
{
current = current->pNext; // пердвг врмн укз на его укз на слд элмнт
}
current->pNext = new Node<T>(data); // присв. укз времен укзателя адрс нвг элмнта
}
Size++;
}
template<typename T>
T & List<T>::operator[](const int index)
{
int counter = 0;
Node<T> *current = this->head; // прсв времен укз адрс укз укз первог элемент
while (current != nullptr) // пока он не равен null
{
if (counter == index) // если счетчик равен указ номеру элемента
{
return current->data; // вернуть элемент T
}
current = current->pNext; // сдвинуть указатель на одну позицию вперед
counter++;
}
}
#endif
#include "pch.h"
#include <iostream>
#include <fstream> // поддержка файлового ввода-вывода
#include <cstdlib> // поддержка exit()
#include <string>
#include "Header.h"
#include "cctype"
const int SIZE = 60;
using namespace std;
int main()
{
setlocale(LC_ALL, "rus");
bool izik = false;
List <string> as;
char filename[SIZE];
char namefile[SIZE];
string abc = "";
string gg;
cout << "Enter name of data file: "; // запрос имени файла данных для чтения текста
cin.getline(filename, SIZE);
ifstream in(filename); // файл для чтения
if (!in.is_open()) // не удалось открыть файл для чтения
{
cout << "Could not open the file " << filename << endl;
cout << "Program terminating.\n";
exit(EXIT_FAILURE);
}
cout << "Enter name of file vvod: "; // запрос имени файла данных для ввода текста
cin.getline(namefile, SIZE);
ifstream nii(namefile); // проверяем существует ли файл в который будем записывать результаты
if (!nii.is_open()) cout << "Warning. Fil dlia chtenia ne syh, sozd nov fil." << filename << endl;
nii.close(); // закрываем его
ofstream ni("rezult.txt"); // теперь открываем настоящий файл для записи
char s = 0; // переменная char для хранения одной буквы
int countik = 0; // количество слов в списке, не элементов, а именно слов
int sount = 0; // количество символов в списке включая пробелы и все остальное кроме слов
do
{
s = in.get();
if ( ( unsigned char(s)>191 && unsigned char(s)<224 ) || ( unsigned char(s) > 223 && unsigned char(s) < 256 ) ) // если буква то закидываем ее в string
{
izik = true;
abc += s;
}
else // если не буква и была буква то записываем слово в список и обнуляем string
{
if ( izik == true )
{
countik++;
as.push_back(abc);
abc.clear();
}
izik = false;
}
if ( (izik == false) ) // если не буква то записываем ее в другой string
gg += s;
else if (!gg.empty()) // если была не буква а теперь буква то символы записываем в string при условии что она есть
{
sount++;
as.push_back(gg);
gg.clear();
} // пробел он видит и записывает
} while ( !in.eof() );
in.close();
for (int i = 0; i < as.GetSize(); i++)
{
cout << as[i];
ni << as[i];
}
if (in.eof()) // достигнут конец файла
cout << endl << "End of file reached.\n";
else
if (in.fail()) // ввод прекращен из-за несоответствия типа данных
cout << "Inpyt terminated for uknown reason.\n";
if (as.GetSize() == 0) // данные для обработки отсутствуют
cout << "No data processed.\n";
int f = 0; // счетчик слов в верхнем регистре
int k = 0; // счетчик количества заглавных букв в данном элементе списка
ni << endl;
ni << "Список слов в верхнем регистре: "<< endl;
for ( int i = 0; i < (countik + sount); i++ ) // цикл перебирает все элементы списка
{
for (int z = 0; z < as[i].size(); z++) // цикл перебирает все буквы рассматриваемого элемента списка
{
if ( (unsigned char(as[i][z]) > 191) && (unsigned char(as[i][z]) < 224) ) // если буква элемента заглавная инкремент К
k++;
}
if (k == as[i].size()) // если количество букв в элементе списка равно числу К то все буквы элемента списка заглавные
{
ni << f+1 << ") " << as[i] << endl; // а значит записать элемент списка в файлик
f++; // инкремент счетчика слов с заглавными буквами
}
k = 0;
}
ni << "Состояние списка:" << endl;
ni << "Всего " << f << " слов в верхнем регистре" << endl;
ni << "Всего " << countik << " слов." << endl;
ni << "Всего " << sount << " оставшихся символов включая пробелы.";
ni.close(); // закрыть файл в который переписали текст
return 0;
} |
|