aboutsummaryrefslogtreecommitdiff
path: root/additional2/д).cpp
diff options
context:
space:
mode:
authorSyndamia <kamen@syndamia.com>2023-12-05 10:50:59 +0200
committerSyndamia <kamen@syndamia.com>2023-12-05 10:50:59 +0200
commit6c84273107288d6c97c80117b0743dd5b8188144 (patch)
tree4f24546e756f1c232176e4b2f3b461a3f7b0fb82 /additional2/д).cpp
parent860b536038b161d1d24028f00030902728824c18 (diff)
downloadupp-2023-solutions-6c84273107288d6c97c80117b0743dd5b8188144.tar
upp-2023-solutions-6c84273107288d6c97c80117b0743dd5b8188144.tar.gz
upp-2023-solutions-6c84273107288d6c97c80117b0743dd5b8188144.zip
[a2] Added solutions for first 5 points
Diffstat (limited to 'additional2/д).cpp')
-rw-r--r--additional2/д).cpp238
1 files changed, 238 insertions, 0 deletions
diff --git a/additional2/д).cpp b/additional2/д).cpp
new file mode 100644
index 0000000..29dc5a1
--- /dev/null
+++ b/additional2/д).cpp
@@ -0,0 +1,238 @@
+#include <iostream>
+#include <cstring>
+
+void resize(char**& text, int& size) {
+ char** biggerText = new char*[size * 2];
+ for (int i = 0; i < size; i++) {
+ biggerText[i] = text[i];
+ }
+ delete[] text;
+ text = biggerText;
+ size *= 2;
+}
+
+// б) подточка
+
+void skipWhiteSpace(char*& str) {
+ while (str[0] == ' ') {
+ str++;
+ }
+}
+
+void extractCommand(char* line, char**& commandAndParameters, int& size) {
+ skipWhiteSpace(line);
+
+ if (line[0] != ':') {
+ commandAndParameters = nullptr;
+ size = 0;
+ return;
+ }
+ line++;
+
+ skipWhiteSpace(line);
+
+ size = 0;
+ int reservedSize = 2;
+ commandAndParameters = new char*[reservedSize];
+
+ commandAndParameters[0] = new char[2];
+ commandAndParameters[0][0] = line[0];
+ commandAndParameters[0][1] = '\0';
+ size++;
+
+
+ line++;
+
+ skipWhiteSpace(line);
+
+ // в този цикъл изкарваме конкретните аргументи
+ while (line[0] != '\0') {
+ // ако commandAndParameters не може да побере още един параметър
+ if (size == reservedSize) {
+ resize(commandAndParameters, reservedSize);
+ }
+
+ // дължината на сегашния параметър
+ int parameterLength = 0;
+ for (int i = 0; line[i] != ' ' && line[i] != '\0'; i++) {
+ parameterLength++;
+ }
+
+ // вкарваме сегашния параметър в commandAndParameters
+ commandAndParameters[size] = new char[parameterLength+1];
+ for (int i = 0; i < parameterLength; i++) {
+ commandAndParameters[size][i] = line[i];
+ }
+ commandAndParameters[size][parameterLength] = '\0';
+ size++;
+
+ line += parameterLength;
+ skipWhiteSpace(line);
+ }
+}
+
+// в) подточка
+
+int digitsLength(int num) {
+ if (num == 0) return 1;
+ int length = 0;
+ while (num != 0) {
+ num /= 10;
+ length++;
+ }
+ return length;
+}
+
+void printNumber(int num, int digitLength) {
+ int printZeroes = digitLength - digitsLength(num);
+ while (printZeroes > 0) {
+ std::cout << "0";
+ }
+ std::cout << num << " ";
+}
+
+void print(char** text, int count) {
+ int countLength = digitsLength(count);
+ for (int i = 0; i < count; i++) {
+ printNumber(i+1, countLength);
+ std::cout << text[i] << std::endl;
+ }
+}
+
+// д) подточка
+
+void deleteRow(char**& text, int& size, int& count, int rowNumber) {
+ if (rowNumber <= 0 || count < rowNumber) {
+ std::cout << "; Invalid row number" << std::endl;
+ return;
+ }
+
+ // Освобождаваме паметта на реда
+ rowNumber--;
+ delete[] text[rowNumber];
+
+ // Преместваме всички редове "назад" с една позиция (вече имаме "дупка" в масива)
+ for (int i = rowNumber; i < count - 1; i++) {
+ text[i] = text[i+1];
+ }
+ text[count-1] = nullptr;
+ count--;
+
+ // Променяме размера на text, този код е доста близък до кода при resize
+ if (count == 0) {
+ return;
+ }
+
+ char** smallerText = new char*[count];
+ for (int i = 0; i < count; i++) {
+ smallerText[i] = text[i];
+ }
+ delete[] text;
+ text = smallerText;
+ size = count;
+}
+
+void tryExcessParametersError(int parametersSize, int maxSize) {
+ // Изваждаме 1, защото parametersSize включва и самата буква, определяща командата
+ if (parametersSize - 1 > maxSize) {
+ std::cout << "; Excess parameters" << std::endl;
+ }
+}
+
+bool tryNotEnoughParametersError(int parametersSize, int minSize) {
+ // Изваждаме 1, защото parametersSize включва и самата буква, определяща командата
+ if (parametersSize - 1 < minSize) {
+ std::cout << "; Not enough parameters" << std::endl;
+ }
+ return parametersSize - 1 >= minSize;
+}
+
+bool tryParameterIsNumber(char* param) {
+ while (param[0] != '\0') {
+ if (param[0] < '0' || param[0] > '9') {
+ std::cout << "; Invalid parameter type" << std::endl;
+ return false;
+ }
+ param++;
+ }
+ return true;
+}
+
+int main() {
+ int size = 2; // колко клетки сме заделили (колко редове можем да вкараме)
+ int count = 0; // колко клетки използваме (колко редове сме вкарали)
+ char** text = new char*[2];
+
+ char buf[1024];
+ std::cin.getline(buf, 1024, '\n');
+ bool stopProgram = false;
+ while (!stopProgram) {
+ // ако text не може да запази още един ред
+ if (count == size) {
+ resize(text, size);
+ }
+
+ char** commandAndParameters;
+ int commandAndParametersSize;
+ extractCommand(buf, commandAndParameters, commandAndParametersSize);
+ // ако сегашния ред не е команда
+ if (commandAndParametersSize == 0) {
+ // вкарваме сегашния ред в text
+ int lineLength = strlen(buf);
+
+ text[count] = new char[lineLength + 1];
+ for (int i = 0; i < lineLength; i++) {
+ text[count][i] = buf[i];
+ }
+ text[count][lineLength] = '\0';
+ count++;
+ }
+ else {
+ bool canCont;
+ switch (commandAndParameters[0][0]) {
+ // в) подточка
+ case 'P': tryExcessParametersError(commandAndParametersSize, 0);
+ print(text, count);
+ break;
+ // г) подточка
+ case 'Q': tryExcessParametersError(commandAndParametersSize, 0);
+ stopProgram = true;
+ break;
+ // д) подточка
+ case 'D': tryExcessParametersError(commandAndParametersSize, 1);
+ // Ако има достатъчно параметри
+ canCont = tryNotEnoughParametersError(commandAndParametersSize, 1);
+ if (!canCont) break;
+ // Ако параметъра е число
+ canCont = tryParameterIsNumber(commandAndParameters[1]);
+ if (!canCont) break;
+
+ deleteRow(text, size, count, atoi(commandAndParameters[1]));
+ break;
+ default: std::cout << "; Not an editor command" << std::endl; break;
+ }
+
+ // освобождаваме памет
+ for (int i = 0; i < commandAndParametersSize; i++) {
+ delete[] commandAndParameters[i];
+ }
+ delete[] commandAndParameters;
+ }
+
+ // вземаме следващия ред
+ if (!stopProgram) {
+ std::cin.getline(buf, 1024, '\n');
+ }
+ }
+
+ // изкарваме всички редове
+ for (int i = 0; i < count; i++) {
+ std::cout << text[i] << std::endl;
+ }
+
+ // освобождаваме памет
+ for (int i = 0; i < count; i++) {
+ delete[] text[i];
+ }
+ delete[] text;
+}