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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
|
# Допълнително упражнение 2 - УПП, 04.12.2023
\n
GitHub classroom: [url https://classroom.github.com/a/CrerXpf6 classroom.github.com/a/CrerXpf6]
.important
Следете внимателно дали триете всичката си динамична памет коректно на всяка подточка!
Случвало се е на контролни да се пишат двойки ако всичко друго е коректно, но има неизтрита памет!
## Задача - текстов редактор
Ще направим един прост текстов редактор.
От входа ще получавате редове текст, в общия случай редовете ще бъдат някакво текстово съдъражение, което ще трябва да запазите в паметта.
Определени редове ще имат команди, чрез които ще [*редактирате*] вече въведения текст.
Задачата е сравнително голяма, затова е разделена на подточки, като всяка надгражда предходната.
### а) въвеждане на текст без команди
Като за начало, нека да имплементираме запазването на текст.
От конзолата ще получавате редове текст, всеки ред ще е с максимална дължина от 1024 знака, след това трябва да го запазите.
.important
Може да използвате масив със статична дължина за буфер, обаче трябва да използвате възможно най-малко памет за "перманентното" запазване на реда текст във вашата програма.
Използвайте многомерен масив за запазване на редовете, вместо всичко да се запазва в един голям низ.
Това е нужно за бъдещи подточки.
[*Само за тестване*], набързо имплементирайте проверка, ако първата буква от реда е [`Q`], тогава програмата да спре да приема вход, да изкара въведения текст до сега и да приключи.
[=Пример:=]
[*Смесен вход/изход*]
```terminal
DAY HAD DAWNED COLD AND GRAY WHEN
the man turned aside from the main Yukon trail. He climbed the high
earth-bank where a little-traveled trail led east through the pine for-
est. It was a high bank, and he paused to breathe at the top.
Q
DAY HAD DAWNED COLD AND GRAY WHEN
the man turned aside from the main Yukon trail. He climbed the high
earth-bank where a little-traveled trail led east through the pine for-
est. It was a high bank, and he paused to breathe at the top.
### б) функция за извеждане на команди
Команда е един ред текст, като първата буква, различна от шпация, е [`:`].
След нея има нула или повече шпации и още една буква, тази буква определя коя команда искаме да използваме.
В зависимост от командата, може да имаме параметри, поставени след буквата за командата.
Параметрите не съдържат шпации и параметрите са разделени помежду си с поне една шпация.
Тоест, един команден ред ще бъде в този формат (като нещата в квадратните скоби са описания, какво има на конкретното място):
[≥0 шпации]:[≥0 шпации][буква][≥0 шпации][параметър 1][≥1 шпации][параметър 2]...[≥1 шпации][последен параметър]
Командите не се запазват като част от текста.
Имплементирайте функция [`extractCommand`], която приема низ.
Ако низът е команда, тогава връща масив от низове, първия от които съдържа буквата, определяща командата, докато останалите низове са параметрите.
Ако низът не е команда, тогава връща празен масив.
.warn
Какво означава празен масив зависи от имплементацията ви.
За предпочитане е да не заделяте памет, когато не е нужно.
.question Как ще върнем масив? Нужно ли е да връщаме бройката елементи?
[*Само за тестване*], след всеки въведен ред, ако е команда, изкарайте извлечените стойности от [`extractCommand`], със запетайки след всяка.
Като при [url #section подточка a)], ако редът започва с [`Q`], спирате приемане на вход и изкарвате запазения текст.
[=Пример:=]
[*Смесен вход/изход*]
```terminal
DAY HAD DAWNED COLD AND GRAY WHEN
:A bcd 012 345
A,bcd,012,345,
the man turned aside from the main Yukon trail. He climbed the high
earth-bank where a little-traveled trail led east through the pine for-
:A
A,
: A
A,
: A abc
A,abc,
est. It was a high bank, and he paused to breathe at the top.
: A123 456 789 A B C
A,123,456,789,A,B,C,
Q
DAY HAD DAWNED COLD AND GRAY WHEN
the man turned aside from the main Yukon trail. He climbed the high
earth-bank where a little-traveled trail led east through the pine for-
est. It was a high bank, and he paused to breathe at the top.
### в) команда print
Имплементирайте функция [`print`], която приема масив, съдържащ целия запазен текст, и го изкарва на екрана, като преди всеки ред изкарва неговия номер (първи ред има номер 1, втори има номер 2, так. нат.) с [=вмъкнати водещи нули=] (така че всяко число да бъде съставено от един и същ брой знаци).
Ако текстът е празен, не изкарва нищо.
Тоест, ако сме въвели текст от 7 реда, [`print`] ще изкара:
```terminal
1 First line
2 Second line
...
7 Last line
Ако сме въвели 23 реда:
```terminal
01 First line
02 Second line
...
09 Ninth line
10 Tenth line
11 Eleventh line
...
23 Last line
Ако сме въвели 130 реда:
```terminal
001 First line
...
009 Ninth line
010 Tenth line
...
099 99th line
100 100th line
...
130 Last line
Командата, която използва тази функция, се определя с главната буква [`P`] и няма параметри.
За всички команди (за момента само [`P`]):
.bulleted
- Обновете програмата, така че при валидна команда, да изпълни съответната и функция и да продължи изпълнение.
- Ако срещнете недефинирана команда, трябва да изкарате на екрана "; Not an editor command" и изпълнението на програмата да продължи.
- Ако срещнете допълнителни/излишни параметри, трябва да изкарате "; Excess parameters", но функцията да се изпълни с коректния брой параметри.
[=Пример:=]
[*Смесен вход/изход*]
```terminal
DAY HAD DAWNED COLD AND GRAY WHEN
:P
1 DAY HAD DAWNED COLD AND GRAY WHEN
:M
; Not an editor command
the man turned aside from the main Yukon trail. He climbed the high
earth-bank where a little-traveled trail led east through the pine for-
:P A 7 n
; Excess parameters
1 DAY HAD DAWNED COLD AND GRAY WHEN
2 the man turned aside from the main Yukon trail. He climbed the high
3 earth-bank where a little-traveled trail led east through the pine for-
est. It was a high bank, and he paused to breathe at the top.
Q
DAY HAD DAWNED COLD AND GRAY WHEN
the man turned aside from the main Yukon trail. He climbed the high
earth-bank where a little-traveled trail led east through the pine for-
est. It was a high bank, and he paused to breathe at the top.
### г) команда quit
Вече може да премахнете временната функционалност, където ако реда започва с [`Q`] програмата спира и изкарва целия текст.
Добавете командата [`Q`], която изкарва на екрана целия текст (без номера на редове) и спира програмата.
[=Примери:=]
[*Смесен вход/изход*]
```terminal
DAY HAD DAWNED COLD AND GRAY WHEN
the man turned aside from the main Yukon trail. He climbed the high
:Q
DAY HAD DAWNED COLD AND GRAY WHEN
the man turned aside from the main Yukon trail. He climbed the high
```terminal
DAY HAD DAWNED COLD AND GRAY WHEN
the man turned aside from the main Yukon trail. He climbed the high
:Q 1 2 3
; Excess parameters
DAY HAD DAWNED COLD AND GRAY WHEN
the man turned aside from the main Yukon trail. He climbed the high
### д) команда delete
Имплементирайте функцията [`deleteRow`], която получава целия текст, въведен до сега, и номер на реда (редовете се индексират от 1 до N).
Тя променя текста, като премахва реда на дадения номер.
.important Не забравяйте да промените размера на масива с низове! Не е решение просто да промените указателя към дадения ред на [`nullptr`], не искаме да използваме излишна памет.
.question Какъв ще бъде типа на аргумента, който приема целия текст?
Добавете командата [`D`], която приема един параметър - цяло положително число, и го прилага върху функцията [`deleteRow`].
Ако номера на реда е невалиден, трябва да изкарате съобщение "; Invalid row number".
Имплементирайте следните функционалности за всички команди:
.bulleted
- Ако срещнете команда, на която не са и подадени нужния брой параметри, изкарайте съобщението "; Not enough parameters" и продължете изпълнение.
- Ако даден параметър на команда е от невалиден тип (подадени букви, когато се иска число, примерно), изкарайте "; Invalid parameter type".
Единствените типове на параметри са цели числа и произволни низове (без шпации).
[=Пример:=]
[*Смесен вход/изход*]
```terminal
dAY HAD DAWNED COLD AND GRAY WHEN
:P
1 dAY HAD DAWNED COLD AND GRAY WHEN
:D 1
:P
DAY HAD DAWNED COLD AND GRAY WHEN
the man turned aside from the main Yukon trail. He climbed the high
earth-bank where a little-traveled trail led east through the pine for-
est. It was a high bank, and he paused to breathe at the top.
:P
1 DAY HAD DAWNED COLD AND GRAY WHEN
2 the man turned aside from the main Yukon trail. He climbed the high
3 earth-bank where a little-traveled trail led east through the pine for-
4 est. It was a high bank, and he paused to breathe at the top.
:D 0
; Invalid row number
:D 8
; Invalid row number
:D A
; Invalid parameter type
:D 4 8 9
; Excess parameters
:P
1 DAY HAD DAWNED COLD AND GRAY WHEN
2 the man turned aside from the main Yukon trail. He climbed the high
3 earth-bank where a little-traveled trail led east through the pine for-
:Q
DAY HAD DAWNED COLD AND GRAY WHEN
the man turned aside from the main Yukon trail. He climbed the high
earth-bank where a little-traveled trail led east through the pine for-
### e) команда insert
Имплементирайте функция [`insertRow`], която приема целия текст, низ и номер на реда.
Функцията вмъква низа в целия текст като ред [=над=] този на подадения номер.
Ако номерът е над броя въведени редове до сега, редът се вмъква като последен.
Добавете команда [`O`], която приема един параметър - неотрицателен ред.
Следващия написан ред ще се вмъкне преди реда на дадения номер, използвайки функцията [`insertRow`].
Ако номера е невалиден изкарва "; Invalid row number".
[=Пример:=]
[*Смесен вход/изход*]
```terminal
the man turned aside from the main Yukon trail. He climbed the high
:P
1 the man turned aside from the main Yukon trail. He climbed the high
:O 1
DAY HAD DAWNED COLD AND GRAY WHEN
:P
1 DAY HAD DAWNED COLD AND GRAY WHEN
2 the man turned aside from the main Yukon trail. He climbed the high
:O 0
; Invalid row number
est. It was a high bank, and he paused to breathe at the top.
:P
1 DAY HAD DAWNED COLD AND GRAY WHEN
2 the man turned aside from the main Yukon trail. He climbed the high
3 est. It was a high bank, and he paused to breathe at the top.
:O 3
earth-bank where a little-traveled trail led east through the pine for-
:P
1 DAY HAD DAWNED COLD AND GRAY WHEN
2 the man turned aside from the main Yukon trail. He climbed the high
3 earth-bank where a little-traveled trail led east through the pine for-
4 est. It was a high bank, and he paused to breathe at the top.
:O 10
He excused
:Q
1 DAY HAD DAWNED COLD AND GRAY WHEN
2 the man turned aside from the main Yukon trail. He climbed the high
3 earth-bank where a little-traveled trail led east through the pine for-
4 est. It was a high bank, and he paused to breathe at the top.
5 He excused
### ж) команда join
Имплементирайте функция [`joinRows`], която приема текстът, въведен до сега, и номер на ред N.
Функцията вмъква текста от ред N+1 в края на ред N, като ги разделя с една шпация.
Ред N+1 се изтрива.
Ако N е 0 или номера на последния ред, не прави нищо.
.important Не забравяйте да промените размера на масива с низове! Не е решение просто да промените указателя към дадения ред на [`nullptr`], не искаме да използваме излишна памет.
Добавете команда [`J`], която приема номер на ред - положително число.
Следващия ред ще се вмъкне в края на сегашния, с една шпация между тях, използвайки функцията [`joinRows`].
При подаден невалиден ред изкарвате "; Invalid row number".
[=Пример:=]
[*Смесен вход/изход*]
```terminal
DAY HAD DAWNED
COLD
AND GRAY WHEN
the man turned aside from the main Yukon trail. He climbed the high
:P
1 DAY HAD DAWNED
2 COLD
3 AND GRAY WHEN
4 the man turned aside from the main Yukon trail. He climbed the high
:J 2
:P
1 DAY HAD DAWNED
2 COLD AND GRAY WHEN
3 the man turned aside from the main Yukon trail. He climbed the high
:J 1
:P
1 DAY HAD DAWNED COLD AND GRAY WHEN
2 the man turned aside from the main Yukon trail. He climbed the high
:J 0
:J 2
:J 8
; Invalid row number
:Q
DAY HAD DAWNED COLD AND GRAY WHEN
the man turned aside from the main Yukon trail. He climbed the high
### з) команда word info
Имплементирайте функция [`wordOccurrences`], която приема целия текст и дума (низ без шпации).
Тя изкарва на екрана броя на срещания на дадената дума в целия текст, като изхода е във формата "; N occurrences" (където N е броя на срещания).
[*Подсказвам, че за следващата подточка ще е полезно ако първо имплементирате функция, която връща броя срещания на дума в един ред.*]
Добавете команда [`n`], която приема един аргумент - низ беш шпации.
Използвайки [`wordOccurrences`] изкарва броя срещания на дадена дума в целия текст.
[=Пример:=]
[*Смесен вход/изход*]
```terminal
DAY HAD DAWNED COLD AND GRAY WHEN
the man turned aside from the main Yukon trail. He climbed the high
earth-bank where a little-traveled trail led east through the pine for-
est. It was a high bank, and he paused to breathe at the top.
:n the
; 6 occurrences
:n earth
; 0 occurrences
:n earth-bank
; 1 occurrences
:n .
; 3 occurrences
:Q
DAY HAD DAWNED COLD AND GRAY WHEN
the man turned aside from the main Yukon trail. He climbed the high
earth-bank where a little-traveled trail led east through the pine for-
est. It was a high bank, and he paused to breathe at the top.
### и) команда word substitute
Имплементирайте функция [`substituteWord`], която приема целия текст и две думи (низове без шпации).
В текстът, всяко срещане на първата дума е заменено с втората дума.
.question Какво ще стане с размера на един ред, ако някоя дума/някои думи трябва да се заменят?
Добавете команда [`s`], която приема две думи - низове без шпации.
Използвайки функцията [`substituteWord`] замества всяко срещане на първата дума с втората.
```terminal
DAY HAD DAWNED COLD AND GRAY WHEN
the man turned aside from the main Yukon trail. He climbed the high
earth-bank where a little-traveled trail led east through the pine for-
est. It was a high bank, and he paused to breathe at the top.
:s the of
:p
1 DAY HAD DAWNED COLD AND GRAY WHEN
2 of man turned aside from of main Yukon trail. He climbed of high
3 earth-bank where a little-traveled trail led east through of pine for-
4 est. It was a high bank, and he paused to breaof at of top.
:s of the
1 DAY HAD DAWNED COLD AND GRAY WHEN
2 the man turned aside from the main Yukon trail. He climbed the high
3 earth-bank where a little-traveled trail led east through the pine for-
4 est. It was a high bank, and he paused to breathe at the top.
:s . !
1 DAY HAD DAWNED COLD AND GRAY WHEN
2 the man turned aside from the main Yukon trail! He climbed the high
3 earth-bank where a little-traveled trail led east through the pine for-
4 est! It was a high bank, and he paused to breathe at the top!
:Q
DAY HAD DAWNED COLD AND GRAY WHEN
the man turned aside from the main Yukon trail. He climbed the high
earth-bank where a little-traveled trail led east through the pine for-
est. It was a high bank, and he paused to breathe at the top.
### й) команда word delete
Имплементирайте функция [`deleteWord`], която приема целия текст и дума (низ без шпации).
В текстът, всяко срещане на думата, заедно с [*излишните*] шпации около нея, са премахнати.
Ето в кои случаи шпации са излишни (където "WORD" е подадената дума, която ще изтрием, а "\_" е някаква буква, която не е шпация):
.bulleted
- [`WORD _`] (WORD е в началото на реда или има знаци преди нея) - шпацията след думата е излишна, трябва да стане [`_`].
Отбелязвам, че шпациите в ляво се запазват: [` WORD _`] става [` _`].
- [`_ WORD`] (WORD е в края на реда или има знаци след нея) - шпацията преди думата е излишна, трябва да стане [`_`].
- [`_ WORD _`] - шпацията, която следва думата, е излишна, тоест трябва да стане [`_ _`].
Трябва да отбележа, че шпациите в ляво се запазват така както са: [`_ WORD _`] става [`_ _`].
Във всичките случаи, като имам предвид "шпацията е излишна", означава че тази шпация, заедно с всички съседни.
Тоест, [`WORD _`] трябва да стане [`_`], а не [` _`].
Добавете команда [`d`], която приема един параметър - дума, низ без шпации.
Използвайки функцията [`deleteWord`] премахва самата дума и излишните шпации.
```terminal
DAY HAD DAWNED COLD AND GRAY WHEN
the man turned aside from the main Yukon trail. He climbed the high
earth-bank where a little-traveled trail led east through the pine for-
est. It was a high bank, and he paused to breathe at the top.
:d the
:Q
DAY HAD DAWNED COLD AND GRAY WHEN
man turned aside from main Yukon trail. He climbed high
earth-bank where a little-traveled trail led east through pine for-
est. It was a high bank, and he paused to brea at top.
|