oshuej

Untitled

Jun 8th, 2020
914
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 22.55 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #define MALLOC_ERROR 4
  5.  
  6. const unsigned int MAX_LENGTH = 1 * 1024 * 1024;  // Не выделять больше мегабайта памяти
  7. const unsigned int CHUNK_SIZE = 1024;             // Выделять блоками по килобайту
  8.  
  9. typedef struct {
  10.     int rowIndex;
  11.     int length;
  12.     int wordStartIndex;
  13.     int wordEndIndex;
  14. } PositionInText;
  15.  
  16. void readString(char *string, size_t *string_size);
  17.  
  18. char** specialReadText(
  19.         char *delimiters,
  20.         size_t *string_size,
  21.         int maxDelimitersRepetitions,
  22.         int numberOfStrings,
  23.         PositionInText *shortestWord,
  24.         PositionInText *longestWord
  25. );
  26.  
  27. void insertLongestInsteadShortest(
  28.         char **inputText,
  29.         char **newText,
  30.         char *delimitersArray,
  31.         int numberOfString,
  32.         PositionInText shortestWord,
  33.         PositionInText longestWord
  34. );
  35.  
  36. void insertShortestInsteadLongest(
  37.         char **inputText,
  38.         char **newText,
  39.         char *delimitersArray,
  40.         int numberOfString,
  41.         PositionInText shortestWord,
  42.         PositionInText longestWord
  43. );
  44.  
  45. void memory_error();
  46.  
  47. int main() {
  48.  
  49. //    Ввести строку символов разделителей, число, количество строк текста и текст.
  50. //    В процессе ввода строк текста не записывать повторяющиеся после слов символы разделители,
  51. //    если их количество превышает заданное до ввода текста некоторое число.
  52. //    В строках введенного текста поменять местами слова,
  53. //    имеющие максимальную и минимальную длины и оставить между словами по одному разделителю.
  54. //    Строки, в которых перестановок не было, удалить.
  55. //    Вывести преобразованный текст.
  56.  
  57.     size_t delimitersArray_size = CHUNK_SIZE;
  58.     char *delimitersArray = malloc(delimitersArray_size);
  59.     if (delimitersArray == NULL) {
  60.         memory_error();
  61.     }
  62.  
  63.     printf("Введите символы-разделители: ");
  64.  
  65.     // считывание символов-разделителей
  66.     readString(delimitersArray, &delimitersArray_size);
  67.  
  68.     int numberOfStrings = 0;
  69.     printf("Введите количество строк текста: ");
  70.     scanf("%d", &numberOfStrings);
  71.  
  72.     int maxDelimitersRepetitions = 0;
  73.     printf("Введите максимальное количество повторений символов-разделителей: ");
  74.     scanf("%d", &maxDelimitersRepetitions);
  75.  
  76.     size_t inputText_size = CHUNK_SIZE;
  77.     char **inputText = (char**) malloc(inputText_size);
  78.     if (inputText == NULL) {
  79.         memory_error();
  80.     }
  81.  
  82.     PositionInText  shortestWord = {0, (int) MAX_LENGTH, 0, 0},
  83.                     longestWord = {0, 0, 0, 0};
  84.  
  85.     printf("Введите текст: \n");
  86.  
  87.     getchar();                  // перехват ложной новой строки
  88.  
  89.     // считывание текста
  90.     inputText = specialReadText(
  91.             delimitersArray,
  92.             &inputText_size,
  93.             maxDelimitersRepetitions,
  94.             numberOfStrings,
  95.             &shortestWord,
  96.             &longestWord
  97.             );
  98.  
  99.     char **newText = NULL;
  100.     int newText_numberOfStrings = 0;
  101.     if (shortestWord.rowIndex == longestWord.rowIndex) {
  102.         newText_numberOfStrings = 1;
  103.         newText = malloc(1 * inputText_size);
  104.         newText[0] = malloc(inputText_size);
  105.     } else {
  106.         newText_numberOfStrings = 2;
  107.         newText = malloc(2 * inputText_size);
  108.         newText[0] = malloc(inputText_size);
  109.         newText[1] = malloc(inputText_size);
  110.     }
  111.     if (newText == NULL) {
  112.         memory_error();
  113.     }
  114.  
  115.     if (newText_numberOfStrings == 1) {
  116.         int counter = 0, numberOfString = 0, isConsistentDelimiter = 0;
  117.         if (shortestWord.wordStartIndex < longestWord.wordStartIndex) {
  118.  
  119.             // записываем символы от 0 до начала самого короткого слова
  120.             for (int i = 0; i < shortestWord.wordStartIndex; i++) {
  121.  
  122.                 // этот цикл (здесь и далее) проверяет, идут ли у нас подряд несколько разделителей
  123.                 for (int j = 0; j < strlen(delimitersArray); j++) {
  124.                     if (inputText[shortestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
  125.                         for (int k = 0; k < strlen(delimitersArray); k++) {
  126.                             if (inputText[shortestWord.rowIndex][i - 1] == delimitersArray[k]) {
  127.                                 isConsistentDelimiter = 1;
  128.                                 break;
  129.                             }
  130.                         }
  131.                         break;
  132.                     }
  133.                 }
  134.                 if (isConsistentDelimiter == 0) {
  135.                     newText[numberOfString][counter] = inputText[shortestWord.rowIndex][i];
  136.                     counter++;
  137.                 }
  138.                 isConsistentDelimiter = 0;
  139.             }
  140.  
  141.             // записываем самое длинное слово (вместо самого короткого)
  142.             for (int i = longestWord.wordStartIndex; i <= longestWord.wordEndIndex; i++) {
  143.                 newText[numberOfString][counter] = inputText[longestWord.rowIndex][i];
  144.                 counter++;
  145.             }
  146.  
  147.             // записываем от конца самого короткого слова до начала самого длинного
  148.             for (int i = shortestWord.wordEndIndex + 1; i < longestWord.wordStartIndex; i++) {
  149.                 for (int j = 0; j < strlen(delimitersArray); j++) {
  150.                     if (inputText[shortestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
  151.                         for (int k = 0; k < strlen(delimitersArray); k++) {
  152.                             if (inputText[shortestWord.rowIndex][i - 1] == delimitersArray[k]) {
  153.                                 isConsistentDelimiter = 1;
  154.                                 break;
  155.                             }
  156.                         }
  157.                         break;
  158.                     }
  159.                 }
  160.                 if (isConsistentDelimiter == 0) {
  161.                     newText[numberOfString][counter] = inputText[shortestWord.rowIndex][i];
  162.                     counter++;
  163.                 }
  164.                 isConsistentDelimiter = 0;
  165.             }
  166.  
  167.             // записываем самое короткое слово (вместо самого длинного)
  168.             for (int i = shortestWord.wordStartIndex; i <= shortestWord.wordEndIndex; i++) {
  169.                 newText[numberOfString][counter] = inputText[shortestWord.rowIndex][i];
  170.                 counter++;
  171.             }
  172.  
  173.             // записываем от конца самого длинного слова до конца строки
  174.             for (int i = longestWord.wordEndIndex + 1; i < strlen(inputText[longestWord.rowIndex]); i++) {
  175.                 for (int j = 0; j < strlen(delimitersArray); j++) {
  176.                     if (inputText[longestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
  177.                         for (int k = 0; k < strlen(delimitersArray); k++) {
  178.                             if (inputText[longestWord.rowIndex][i - 1] == delimitersArray[k]) {
  179.                                 isConsistentDelimiter = 1;
  180.                                 break;
  181.                             }
  182.                         }
  183.                         break;
  184.                     }
  185.                 }
  186.                 if (isConsistentDelimiter == 0) {
  187.                     newText[numberOfString][counter] = inputText[longestWord.rowIndex][i];
  188.                     counter++;
  189.                 }
  190.                 isConsistentDelimiter = 0;
  191.             }
  192.         } else {
  193.  
  194.             // записываем символы от 0 до начала самого длинного слова
  195.             for (int i = 0; i < longestWord.wordStartIndex; i++) {
  196.  
  197.                 // этот цикл (здесь и далее) проверяет, идут ли у нас подряд несколько разделителей
  198.                 for (int j = 0; j < strlen(delimitersArray); j++) {
  199.                     if (inputText[longestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
  200.                         for (int k = 0; k < strlen(delimitersArray); k++) {
  201.                             if (inputText[longestWord.rowIndex][i - 1] == delimitersArray[k]) {
  202.                                 isConsistentDelimiter = 1;
  203.                                 break;
  204.                             }
  205.                         }
  206.                         break;
  207.                     }
  208.                 }
  209.                 if (isConsistentDelimiter == 0) {
  210.                     newText[numberOfString][counter] = inputText[longestWord.rowIndex][i];
  211.                     counter++;
  212.                 }
  213.                 isConsistentDelimiter = 0;
  214.             }
  215.  
  216.             // записываем самое короткое слово (вместо самого длинного)
  217.             for (int i = shortestWord.wordStartIndex; i <= shortestWord.wordEndIndex; i++) {
  218.                 newText[numberOfString][counter] = inputText[shortestWord.rowIndex][i];
  219.                 counter++;
  220.             }
  221.  
  222.             // записываем от конца самого длинного слова до начала самого короткого
  223.             for (int i = longestWord.wordEndIndex + 1; i < shortestWord.wordStartIndex; i++) {
  224.                 for (int j = 0; j < strlen(delimitersArray); j++) {
  225.                     if (inputText[longestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
  226.                         for (int k = 0; k < strlen(delimitersArray); k++) {
  227.                             if (inputText[longestWord.rowIndex][i - 1] == delimitersArray[k]) {
  228.                                 isConsistentDelimiter = 1;
  229.                                 break;
  230.                             }
  231.                         }
  232.                         break;
  233.                     }
  234.                 }
  235.                 if (isConsistentDelimiter == 0) {
  236.                     newText[numberOfString][counter] = inputText[longestWord.rowIndex][i];
  237.                     counter++;
  238.                 }
  239.                 isConsistentDelimiter = 0;
  240.             }
  241.  
  242.             // записываем самое короткое слово (вместо самого длинного)
  243.             for (int i = longestWord.wordStartIndex; i <= longestWord.wordEndIndex; i++) {
  244.                 newText[numberOfString][counter] = inputText[longestWord.rowIndex][i];
  245.                 counter++;
  246.             }
  247.  
  248.             // записываем от конца самого короткого слова до конца строки
  249.             for (int i = shortestWord.wordEndIndex + 1; i < strlen(inputText[shortestWord.rowIndex]); i++) {
  250.                 for (int j = 0; j < strlen(delimitersArray); j++) {
  251.                     if (inputText[shortestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
  252.                         for (int k = 0; k < strlen(delimitersArray); k++) {
  253.                             if (inputText[shortestWord.rowIndex][i - 1] == delimitersArray[k]) {
  254.                                 isConsistentDelimiter = 1;
  255.                                 break;
  256.                             }
  257.                         }
  258.                         break;
  259.                     }
  260.                 }
  261.                 if (isConsistentDelimiter == 0) {
  262.                     newText[numberOfString][counter] = inputText[shortestWord.rowIndex][i];
  263.                     counter++;
  264.                 }
  265.                 isConsistentDelimiter = 0;
  266.             }
  267.         }
  268.     } else {
  269.         if (shortestWord.rowIndex < longestWord.rowIndex) {
  270.             insertLongestInsteadShortest(
  271.                     inputText,
  272.                     newText,
  273.                     delimitersArray,
  274.                     0,
  275.                     shortestWord,
  276.                     longestWord
  277.             );
  278.             insertShortestInsteadLongest(
  279.                     inputText,
  280.                     newText,
  281.                     delimitersArray,
  282.                     1,
  283.                     shortestWord,
  284.                     longestWord
  285.             );
  286.         } else {
  287.             insertShortestInsteadLongest(
  288.                     inputText,
  289.                     newText,
  290.                     delimitersArray,
  291.                     0,
  292.                     shortestWord,
  293.                     longestWord
  294.             );
  295.             insertLongestInsteadShortest(
  296.                     inputText,
  297.                     newText,
  298.                     delimitersArray,
  299.                     1,
  300.                     shortestWord,
  301.                     longestWord
  302.             );
  303.         }
  304.     }
  305.  
  306.     printf("Исходный текст:\n");
  307.     for (int i = 0; i < numberOfStrings; i++) {
  308.         printf("\"%s\"\n", inputText[i]);
  309.     }
  310.  
  311.     printf("Отформатированный текст:\n");
  312.     for (int i = 0; i < newText_numberOfStrings; i++) {
  313.         printf("\"%s\"\n", newText[i]);
  314.     }
  315.  
  316.     free(delimitersArray);
  317.  
  318.     for (int i = 0; i < newText_numberOfStrings; i++) {
  319.         free(newText[i]);
  320.     }
  321.     free(newText);
  322.  
  323.     return 0;
  324. }
  325.  
  326. void readString(char *string, size_t *string_size) {
  327.     // функция, считывающая текст из консоли
  328.  
  329.     int c = EOF;
  330.  
  331.     for (int i = 0; (c = getchar()) && (c != '\n'); i++) {
  332.         if (i == (*string_size - 1)) {
  333.             // проверяем, есть ли еще свободная память, если нет, то выделяем
  334.             *string_size += i;
  335.             string = realloc(string, *string_size);
  336.             if (string == NULL) {
  337.                 memory_error();
  338.             }
  339.         }
  340.  
  341.         if (*string_size == MAX_LENGTH) {
  342.             // проверяем, достиг ли размер массива максимального значения. Если да, то освобождаем память.
  343.             free(string);
  344.         }
  345.         string[i] = c;
  346.     }
  347. }
  348.  
  349. char** specialReadText(
  350.         char *delimiters,
  351.         size_t *string_size,
  352.         int maxDelimitersRepetitions,
  353.         int numberOfStrings,
  354.         PositionInText *shortestWord,
  355.         PositionInText *longestWord
  356.         ) {
  357.     // функция считывает текст, а также считает длину слов, а также количетсво разделителей
  358.     *string_size = CHUNK_SIZE;
  359.     char **text = (char**) malloc(CHUNK_SIZE);
  360.  
  361.     for (int i = 0; i < numberOfStrings; i++) {
  362.         int c = EOF;
  363.         int countOfDelimitersRepetitions = 0;              // счетчик подряд идущих разделителей
  364.         int wordLength = 0;
  365.  
  366.         text[i] = (char*) malloc(*string_size);
  367.  
  368.         if (text == NULL || text[i] == NULL) {
  369.             memory_error();
  370.         }
  371.  
  372.         for (int j = 0; (c = getchar()); j++) {
  373.             if (c == '\n') {
  374.                 text[i][j] = '\0';
  375.                 text = realloc(text, ((i + 1) * (*string_size)));
  376.  
  377.                 if (text == NULL) {
  378.                     memory_error();
  379.                 }
  380.                 break;
  381.             } else {
  382.                 if (i == (*string_size - 1)) {
  383.                     *string_size += i;
  384.                     text = realloc(text, (i * (*string_size)));
  385.                     if (text == NULL) {
  386.                         memory_error();
  387.                     }
  388.                 }
  389.  
  390.                 if (i == MAX_LENGTH) {
  391.                     free(text);
  392.                     memory_error();
  393.                 }
  394.  
  395.                 int isDelimiter = 0;
  396.                 for (int k = 0; k < strlen(delimiters); k++) {
  397.                     if (c == delimiters[k]) {
  398.                         isDelimiter = 1;
  399.                         break;
  400.                     }
  401.                 }
  402.  
  403.                 if (isDelimiter == 1) {
  404.                     if (longestWord->length < wordLength) {
  405.                         longestWord->length = wordLength;
  406.                         longestWord->rowIndex = i;
  407.                         longestWord->wordStartIndex = j - wordLength;
  408.                         longestWord->wordEndIndex = j;
  409.                     } else if ((shortestWord->length > wordLength) && (wordLength != 0)) {
  410.                         shortestWord->length = wordLength;
  411.                         shortestWord->rowIndex = i;
  412.                         shortestWord->wordStartIndex = j - wordLength;
  413.                         shortestWord->wordEndIndex = j;
  414.                     }
  415.                     wordLength = 0;
  416.                     countOfDelimitersRepetitions++;
  417.                 } else {
  418.                     wordLength++;
  419.                     countOfDelimitersRepetitions = 0;
  420.                 }
  421.  
  422.                 if (countOfDelimitersRepetitions <= maxDelimitersRepetitions) {
  423.                     text[i][j] = c;
  424.                 } else {
  425.                     j--;
  426.                 }
  427.             }
  428.         }
  429.     }
  430.     return text;
  431. }
  432.  
  433. void insertLongestInsteadShortest(
  434.         char **inputText,
  435.         char **newText,
  436.         char *delimitersArray,
  437.         int numberOfString,
  438.         PositionInText shortestWord,
  439.         PositionInText longestWord
  440.         ) {
  441.     int counter = 0;
  442.     int isConsistentDelimiter = 0;
  443.  
  444.     // записываем от 0 до начала самого короткого слова
  445.     for (int i = 0; i < shortestWord.wordStartIndex; i++) {
  446.  
  447.         // этот цикл (здесь и далее) проверяет, идут ли у нас подряд несколько разделителей
  448.         for (int j = 0; j < strlen(delimitersArray); j++) {
  449.             if (inputText[shortestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
  450.                 for (int k = 0; k < strlen(delimitersArray); k++) {
  451.                     if (inputText[shortestWord.rowIndex][i - 1] == delimitersArray[k]) {
  452.                         isConsistentDelimiter = 1;
  453.                         break;
  454.                     }
  455.                 }
  456.                 break;
  457.             }
  458.         }
  459.         if (isConsistentDelimiter == 0) {
  460.             newText[numberOfString][counter] = inputText[shortestWord.rowIndex][i];
  461.             counter++;
  462.         }
  463.         isConsistentDelimiter = 0;
  464.     }
  465.  
  466.     // записываем самое длинное слово (вместо самого короткого)
  467.     for (int i = longestWord.wordStartIndex; i <= longestWord.wordEndIndex; i++) {
  468.         newText[numberOfString][counter] = inputText[longestWord.rowIndex][i];
  469.         counter++;
  470.     }
  471.  
  472.     // записываем от конца самого короткого слова до конца строки
  473.     for (int i = shortestWord.wordEndIndex + 1; i < strlen(inputText[shortestWord.rowIndex]); i++) {
  474.         for (int j = 0; j < strlen(delimitersArray); j++) {
  475.             if (inputText[shortestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
  476.                 for (int k = 0; k < strlen(delimitersArray); k++) {
  477.                     if (inputText[shortestWord.rowIndex][i - 1] == delimitersArray[k]) {
  478.                         isConsistentDelimiter = 1;
  479.                         break;
  480.                     }
  481.                 }
  482.                 break;
  483.             }
  484.         }
  485.         if (isConsistentDelimiter == 0) {
  486.             newText[numberOfString][counter] = inputText[shortestWord.rowIndex][i];
  487.             counter++;
  488.         }
  489.         isConsistentDelimiter = 0;
  490.     }
  491. }
  492.  
  493. void insertShortestInsteadLongest(
  494.         char **inputText,
  495.         char **newText,
  496.         char *delimitersArray,
  497.         int numberOfString,
  498.         PositionInText shortestWord,
  499.         PositionInText longestWord
  500.         ) {
  501.     int counter = 0;
  502.     int isConsistentDelimiter = 0;
  503.  
  504.     // записываем от 0 до начала самаого длинного слова
  505.     for (int i = 0; i < longestWord.wordStartIndex; i++) {
  506.  
  507.         // этот цикл (здесь и далее) проверяет, идут ли у нас подряд несколько разделителей
  508.         for (int j = 0; j < strlen(delimitersArray); j++) {
  509.             if (inputText[longestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
  510.                 for (int k = 0; k < strlen(delimitersArray); k++) {
  511.                     if (inputText[longestWord.rowIndex][i - 1] == delimitersArray[k]) {
  512.                         isConsistentDelimiter = 1;
  513.                         break;
  514.                     }
  515.                 }
  516.                 break;
  517.             }
  518.         }
  519.         if (isConsistentDelimiter == 0) {
  520.             newText[numberOfString][counter] = inputText[longestWord.rowIndex][i];
  521.             counter++;
  522.         }
  523.         isConsistentDelimiter = 0;
  524.     }
  525.  
  526.     // записываем самое короткое слово (вместо самого длинного)
  527.     for (int i = shortestWord.wordStartIndex; i <= shortestWord.wordEndIndex; i++) {
  528.         newText[numberOfString][counter] = inputText[shortestWord.rowIndex][i];
  529.         counter++;
  530.     }
  531.  
  532.     // записываем от конца самого длинного слова до конца строки
  533.     for (int i = longestWord.wordEndIndex + 1; i < strlen(inputText[longestWord.rowIndex]); i++) {
  534.         for (int j = 0; j < strlen(delimitersArray); j++) {
  535.             if (inputText[longestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
  536.                 for (int k = 0; k < strlen(delimitersArray); k++) {
  537.                     if (inputText[longestWord.rowIndex][i - 1] == delimitersArray[k]) {
  538.                         isConsistentDelimiter = 1;
  539.                         break;
  540.                     }
  541.                 }
  542.                 break;
  543.             }
  544.         }
  545.         if (isConsistentDelimiter == 0) {
  546.             newText[numberOfString][counter] = inputText[longestWord.rowIndex][i];
  547.             counter++;
  548.         }
  549.         isConsistentDelimiter = 0;
  550.     }
  551. }
  552.  
  553.  
  554. void memory_error() {
  555.     // необхоидмо вызывать, если не удалось динамически выделить память
  556.     printf("Произошла ошибка. Запросили слишком много памяти??\n");
  557.     exit(MALLOC_ERROR);
  558. }
Advertisement
Add Comment
Please, Sign In to add comment