Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define MALLOC_ERROR 4
- const unsigned int MAX_LENGTH = 1 * 1024 * 1024; // Не выделять больше мегабайта памяти
- const unsigned int CHUNK_SIZE = 1024; // Выделять блоками по килобайту
- typedef struct {
- int rowIndex;
- int length;
- int wordStartIndex;
- int wordEndIndex;
- } PositionInText;
- void readString(char *string, size_t *string_size);
- char** specialReadText(
- char *delimiters,
- size_t *string_size,
- int maxDelimitersRepetitions,
- int numberOfStrings,
- PositionInText *shortestWord,
- PositionInText *longestWord
- );
- void insertLongestInsteadShortest(
- char **inputText,
- char **newText,
- char *delimitersArray,
- int numberOfString,
- PositionInText shortestWord,
- PositionInText longestWord
- );
- void insertShortestInsteadLongest(
- char **inputText,
- char **newText,
- char *delimitersArray,
- int numberOfString,
- PositionInText shortestWord,
- PositionInText longestWord
- );
- void memory_error();
- int main() {
- // Ввести строку символов разделителей, число, количество строк текста и текст.
- // В процессе ввода строк текста не записывать повторяющиеся после слов символы разделители,
- // если их количество превышает заданное до ввода текста некоторое число.
- // В строках введенного текста поменять местами слова,
- // имеющие максимальную и минимальную длины и оставить между словами по одному разделителю.
- // Строки, в которых перестановок не было, удалить.
- // Вывести преобразованный текст.
- size_t delimitersArray_size = CHUNK_SIZE;
- char *delimitersArray = malloc(delimitersArray_size);
- if (delimitersArray == NULL) {
- memory_error();
- }
- printf("Введите символы-разделители: ");
- // считывание символов-разделителей
- readString(delimitersArray, &delimitersArray_size);
- int numberOfStrings = 0;
- printf("Введите количество строк текста: ");
- scanf("%d", &numberOfStrings);
- int maxDelimitersRepetitions = 0;
- printf("Введите максимальное количество повторений символов-разделителей: ");
- scanf("%d", &maxDelimitersRepetitions);
- size_t inputText_size = CHUNK_SIZE;
- char **inputText = (char**) malloc(inputText_size);
- if (inputText == NULL) {
- memory_error();
- }
- PositionInText shortestWord = {0, (int) MAX_LENGTH, 0, 0},
- longestWord = {0, 0, 0, 0};
- printf("Введите текст: \n");
- getchar(); // перехват ложной новой строки
- // считывание текста
- inputText = specialReadText(
- delimitersArray,
- &inputText_size,
- maxDelimitersRepetitions,
- numberOfStrings,
- &shortestWord,
- &longestWord
- );
- char **newText = NULL;
- int newText_numberOfStrings = 0;
- if (shortestWord.rowIndex == longestWord.rowIndex) {
- newText_numberOfStrings = 1;
- newText = malloc(1 * inputText_size);
- newText[0] = malloc(inputText_size);
- } else {
- newText_numberOfStrings = 2;
- newText = malloc(2 * inputText_size);
- newText[0] = malloc(inputText_size);
- newText[1] = malloc(inputText_size);
- }
- if (newText == NULL) {
- memory_error();
- }
- if (newText_numberOfStrings == 1) {
- int counter = 0, numberOfString = 0, isConsistentDelimiter = 0;
- if (shortestWord.wordStartIndex < longestWord.wordStartIndex) {
- // записываем символы от 0 до начала самого короткого слова
- for (int i = 0; i < shortestWord.wordStartIndex; i++) {
- // этот цикл (здесь и далее) проверяет, идут ли у нас подряд несколько разделителей
- for (int j = 0; j < strlen(delimitersArray); j++) {
- if (inputText[shortestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
- for (int k = 0; k < strlen(delimitersArray); k++) {
- if (inputText[shortestWord.rowIndex][i - 1] == delimitersArray[k]) {
- isConsistentDelimiter = 1;
- break;
- }
- }
- break;
- }
- }
- if (isConsistentDelimiter == 0) {
- newText[numberOfString][counter] = inputText[shortestWord.rowIndex][i];
- counter++;
- }
- isConsistentDelimiter = 0;
- }
- // записываем самое длинное слово (вместо самого короткого)
- for (int i = longestWord.wordStartIndex; i <= longestWord.wordEndIndex; i++) {
- newText[numberOfString][counter] = inputText[longestWord.rowIndex][i];
- counter++;
- }
- // записываем от конца самого короткого слова до начала самого длинного
- for (int i = shortestWord.wordEndIndex + 1; i < longestWord.wordStartIndex; i++) {
- for (int j = 0; j < strlen(delimitersArray); j++) {
- if (inputText[shortestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
- for (int k = 0; k < strlen(delimitersArray); k++) {
- if (inputText[shortestWord.rowIndex][i - 1] == delimitersArray[k]) {
- isConsistentDelimiter = 1;
- break;
- }
- }
- break;
- }
- }
- if (isConsistentDelimiter == 0) {
- newText[numberOfString][counter] = inputText[shortestWord.rowIndex][i];
- counter++;
- }
- isConsistentDelimiter = 0;
- }
- // записываем самое короткое слово (вместо самого длинного)
- for (int i = shortestWord.wordStartIndex; i <= shortestWord.wordEndIndex; i++) {
- newText[numberOfString][counter] = inputText[shortestWord.rowIndex][i];
- counter++;
- }
- // записываем от конца самого длинного слова до конца строки
- for (int i = longestWord.wordEndIndex + 1; i < strlen(inputText[longestWord.rowIndex]); i++) {
- for (int j = 0; j < strlen(delimitersArray); j++) {
- if (inputText[longestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
- for (int k = 0; k < strlen(delimitersArray); k++) {
- if (inputText[longestWord.rowIndex][i - 1] == delimitersArray[k]) {
- isConsistentDelimiter = 1;
- break;
- }
- }
- break;
- }
- }
- if (isConsistentDelimiter == 0) {
- newText[numberOfString][counter] = inputText[longestWord.rowIndex][i];
- counter++;
- }
- isConsistentDelimiter = 0;
- }
- } else {
- // записываем символы от 0 до начала самого длинного слова
- for (int i = 0; i < longestWord.wordStartIndex; i++) {
- // этот цикл (здесь и далее) проверяет, идут ли у нас подряд несколько разделителей
- for (int j = 0; j < strlen(delimitersArray); j++) {
- if (inputText[longestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
- for (int k = 0; k < strlen(delimitersArray); k++) {
- if (inputText[longestWord.rowIndex][i - 1] == delimitersArray[k]) {
- isConsistentDelimiter = 1;
- break;
- }
- }
- break;
- }
- }
- if (isConsistentDelimiter == 0) {
- newText[numberOfString][counter] = inputText[longestWord.rowIndex][i];
- counter++;
- }
- isConsistentDelimiter = 0;
- }
- // записываем самое короткое слово (вместо самого длинного)
- for (int i = shortestWord.wordStartIndex; i <= shortestWord.wordEndIndex; i++) {
- newText[numberOfString][counter] = inputText[shortestWord.rowIndex][i];
- counter++;
- }
- // записываем от конца самого длинного слова до начала самого короткого
- for (int i = longestWord.wordEndIndex + 1; i < shortestWord.wordStartIndex; i++) {
- for (int j = 0; j < strlen(delimitersArray); j++) {
- if (inputText[longestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
- for (int k = 0; k < strlen(delimitersArray); k++) {
- if (inputText[longestWord.rowIndex][i - 1] == delimitersArray[k]) {
- isConsistentDelimiter = 1;
- break;
- }
- }
- break;
- }
- }
- if (isConsistentDelimiter == 0) {
- newText[numberOfString][counter] = inputText[longestWord.rowIndex][i];
- counter++;
- }
- isConsistentDelimiter = 0;
- }
- // записываем самое короткое слово (вместо самого длинного)
- for (int i = longestWord.wordStartIndex; i <= longestWord.wordEndIndex; i++) {
- newText[numberOfString][counter] = inputText[longestWord.rowIndex][i];
- counter++;
- }
- // записываем от конца самого короткого слова до конца строки
- for (int i = shortestWord.wordEndIndex + 1; i < strlen(inputText[shortestWord.rowIndex]); i++) {
- for (int j = 0; j < strlen(delimitersArray); j++) {
- if (inputText[shortestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
- for (int k = 0; k < strlen(delimitersArray); k++) {
- if (inputText[shortestWord.rowIndex][i - 1] == delimitersArray[k]) {
- isConsistentDelimiter = 1;
- break;
- }
- }
- break;
- }
- }
- if (isConsistentDelimiter == 0) {
- newText[numberOfString][counter] = inputText[shortestWord.rowIndex][i];
- counter++;
- }
- isConsistentDelimiter = 0;
- }
- }
- } else {
- if (shortestWord.rowIndex < longestWord.rowIndex) {
- insertLongestInsteadShortest(
- inputText,
- newText,
- delimitersArray,
- 0,
- shortestWord,
- longestWord
- );
- insertShortestInsteadLongest(
- inputText,
- newText,
- delimitersArray,
- 1,
- shortestWord,
- longestWord
- );
- } else {
- insertShortestInsteadLongest(
- inputText,
- newText,
- delimitersArray,
- 0,
- shortestWord,
- longestWord
- );
- insertLongestInsteadShortest(
- inputText,
- newText,
- delimitersArray,
- 1,
- shortestWord,
- longestWord
- );
- }
- }
- printf("Исходный текст:\n");
- for (int i = 0; i < numberOfStrings; i++) {
- printf("\"%s\"\n", inputText[i]);
- }
- printf("Отформатированный текст:\n");
- for (int i = 0; i < newText_numberOfStrings; i++) {
- printf("\"%s\"\n", newText[i]);
- }
- free(delimitersArray);
- for (int i = 0; i < newText_numberOfStrings; i++) {
- free(newText[i]);
- }
- free(newText);
- return 0;
- }
- void readString(char *string, size_t *string_size) {
- // функция, считывающая текст из консоли
- int c = EOF;
- for (int i = 0; (c = getchar()) && (c != '\n'); i++) {
- if (i == (*string_size - 1)) {
- // проверяем, есть ли еще свободная память, если нет, то выделяем
- *string_size += i;
- string = realloc(string, *string_size);
- if (string == NULL) {
- memory_error();
- }
- }
- if (*string_size == MAX_LENGTH) {
- // проверяем, достиг ли размер массива максимального значения. Если да, то освобождаем память.
- free(string);
- }
- string[i] = c;
- }
- }
- char** specialReadText(
- char *delimiters,
- size_t *string_size,
- int maxDelimitersRepetitions,
- int numberOfStrings,
- PositionInText *shortestWord,
- PositionInText *longestWord
- ) {
- // функция считывает текст, а также считает длину слов, а также количетсво разделителей
- *string_size = CHUNK_SIZE;
- char **text = (char**) malloc(CHUNK_SIZE);
- for (int i = 0; i < numberOfStrings; i++) {
- int c = EOF;
- int countOfDelimitersRepetitions = 0; // счетчик подряд идущих разделителей
- int wordLength = 0;
- text[i] = (char*) malloc(*string_size);
- if (text == NULL || text[i] == NULL) {
- memory_error();
- }
- for (int j = 0; (c = getchar()); j++) {
- if (c == '\n') {
- text[i][j] = '\0';
- text = realloc(text, ((i + 1) * (*string_size)));
- if (text == NULL) {
- memory_error();
- }
- break;
- } else {
- if (i == (*string_size - 1)) {
- *string_size += i;
- text = realloc(text, (i * (*string_size)));
- if (text == NULL) {
- memory_error();
- }
- }
- if (i == MAX_LENGTH) {
- free(text);
- memory_error();
- }
- int isDelimiter = 0;
- for (int k = 0; k < strlen(delimiters); k++) {
- if (c == delimiters[k]) {
- isDelimiter = 1;
- break;
- }
- }
- if (isDelimiter == 1) {
- if (longestWord->length < wordLength) {
- longestWord->length = wordLength;
- longestWord->rowIndex = i;
- longestWord->wordStartIndex = j - wordLength;
- longestWord->wordEndIndex = j;
- } else if ((shortestWord->length > wordLength) && (wordLength != 0)) {
- shortestWord->length = wordLength;
- shortestWord->rowIndex = i;
- shortestWord->wordStartIndex = j - wordLength;
- shortestWord->wordEndIndex = j;
- }
- wordLength = 0;
- countOfDelimitersRepetitions++;
- } else {
- wordLength++;
- countOfDelimitersRepetitions = 0;
- }
- if (countOfDelimitersRepetitions <= maxDelimitersRepetitions) {
- text[i][j] = c;
- } else {
- j--;
- }
- }
- }
- }
- return text;
- }
- void insertLongestInsteadShortest(
- char **inputText,
- char **newText,
- char *delimitersArray,
- int numberOfString,
- PositionInText shortestWord,
- PositionInText longestWord
- ) {
- int counter = 0;
- int isConsistentDelimiter = 0;
- // записываем от 0 до начала самого короткого слова
- for (int i = 0; i < shortestWord.wordStartIndex; i++) {
- // этот цикл (здесь и далее) проверяет, идут ли у нас подряд несколько разделителей
- for (int j = 0; j < strlen(delimitersArray); j++) {
- if (inputText[shortestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
- for (int k = 0; k < strlen(delimitersArray); k++) {
- if (inputText[shortestWord.rowIndex][i - 1] == delimitersArray[k]) {
- isConsistentDelimiter = 1;
- break;
- }
- }
- break;
- }
- }
- if (isConsistentDelimiter == 0) {
- newText[numberOfString][counter] = inputText[shortestWord.rowIndex][i];
- counter++;
- }
- isConsistentDelimiter = 0;
- }
- // записываем самое длинное слово (вместо самого короткого)
- for (int i = longestWord.wordStartIndex; i <= longestWord.wordEndIndex; i++) {
- newText[numberOfString][counter] = inputText[longestWord.rowIndex][i];
- counter++;
- }
- // записываем от конца самого короткого слова до конца строки
- for (int i = shortestWord.wordEndIndex + 1; i < strlen(inputText[shortestWord.rowIndex]); i++) {
- for (int j = 0; j < strlen(delimitersArray); j++) {
- if (inputText[shortestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
- for (int k = 0; k < strlen(delimitersArray); k++) {
- if (inputText[shortestWord.rowIndex][i - 1] == delimitersArray[k]) {
- isConsistentDelimiter = 1;
- break;
- }
- }
- break;
- }
- }
- if (isConsistentDelimiter == 0) {
- newText[numberOfString][counter] = inputText[shortestWord.rowIndex][i];
- counter++;
- }
- isConsistentDelimiter = 0;
- }
- }
- void insertShortestInsteadLongest(
- char **inputText,
- char **newText,
- char *delimitersArray,
- int numberOfString,
- PositionInText shortestWord,
- PositionInText longestWord
- ) {
- int counter = 0;
- int isConsistentDelimiter = 0;
- // записываем от 0 до начала самаого длинного слова
- for (int i = 0; i < longestWord.wordStartIndex; i++) {
- // этот цикл (здесь и далее) проверяет, идут ли у нас подряд несколько разделителей
- for (int j = 0; j < strlen(delimitersArray); j++) {
- if (inputText[longestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
- for (int k = 0; k < strlen(delimitersArray); k++) {
- if (inputText[longestWord.rowIndex][i - 1] == delimitersArray[k]) {
- isConsistentDelimiter = 1;
- break;
- }
- }
- break;
- }
- }
- if (isConsistentDelimiter == 0) {
- newText[numberOfString][counter] = inputText[longestWord.rowIndex][i];
- counter++;
- }
- isConsistentDelimiter = 0;
- }
- // записываем самое короткое слово (вместо самого длинного)
- for (int i = shortestWord.wordStartIndex; i <= shortestWord.wordEndIndex; i++) {
- newText[numberOfString][counter] = inputText[shortestWord.rowIndex][i];
- counter++;
- }
- // записываем от конца самого длинного слова до конца строки
- for (int i = longestWord.wordEndIndex + 1; i < strlen(inputText[longestWord.rowIndex]); i++) {
- for (int j = 0; j < strlen(delimitersArray); j++) {
- if (inputText[longestWord.rowIndex][i] == delimitersArray[j] && i != 0) {
- for (int k = 0; k < strlen(delimitersArray); k++) {
- if (inputText[longestWord.rowIndex][i - 1] == delimitersArray[k]) {
- isConsistentDelimiter = 1;
- break;
- }
- }
- break;
- }
- }
- if (isConsistentDelimiter == 0) {
- newText[numberOfString][counter] = inputText[longestWord.rowIndex][i];
- counter++;
- }
- isConsistentDelimiter = 0;
- }
- }
- void memory_error() {
- // необхоидмо вызывать, если не удалось динамически выделить память
- printf("Произошла ошибка. Запросили слишком много памяти??\n");
- exit(MALLOC_ERROR);
- }
Advertisement
Add Comment
Please, Sign In to add comment