C11, MinGW 8.1.0 x64, VS Code 1.33
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
6.8 KiB

#include <stdio.h>
#include <stdlib.h>
// структура объекта подстроки
typedef struct Substring{
char *String;
unsigned int Begin;
unsigned int End;
unsigned int Length;
} Substring;
// коллекция которая хранит в себе набор подстрок
typedef struct SubstringCollection {
Substring *Collection;
unsigned int Count;
} SubstringCollection;
// метод для удаления подстроки из коллекции подстрок
SubstringCollection RemoveFromCollection(SubstringCollection collection, int index) {
for (int i = index; i < collection.Count - 1; i++) {
collection.Collection[i] = collection.Collection[i+1];
}
collection.Count--;
collection.Collection = realloc(collection.Collection, sizeof(Substring) * (collection.Count + 1));
return collection;
}
// проверяем символ, заглавный ли он или нет
_Bool isCapital(char c) {
if((65 <= c) && (c <= 90)) {
return 1;
}
return 0;
}
// возвращает любую часть строки начинающуюся и заканчивающуся на по номеру символа
char* GetSubstring(char *inputString, unsigned int begin, unsigned int end) {
unsigned int length = end - begin;
char *substring = (char *) calloc(length + 1, sizeof(char));
for(int i = begin; i != end; i++) {
substring[i - begin] = inputString[i];
}
substring[length + 1] = '\0';
return substring;
}
// удалить русские символы с конца строки (может удалять что-то еще, я хз)
Substring RemoveRussianSymbolsAtTheEnd(char *string, unsigned int stringLength) {
for(int i = stringLength; i != 0; i--) {
if (string[i] < 0) {
stringLength--;
}
else if (string[i] > 0)
break;
}
Substring result = { GetSubstring(string, 0, stringLength), (unsigned int) 0, stringLength, stringLength};
return result;
}
// проверить строку на наличие в ней скобок различного типа
_Bool CheckForParentheses(char *string, unsigned int stringLength) {
int parentheses[] = { 40, 41, 60, 62, 91, 93, 123, 125};
for(int i = 0; i != stringLength; i++) {
for (int j = 0; j != 8; j++) {
if (string[i] == parentheses[j])
return 1;
}
}
return 0;
}
// найти одну подстроку выделенную латинскими заглавными символами
Substring FindSubstring(char *inputString, unsigned int length) {
unsigned int begin = 0;
for(int i = 0; i <= length; i++) {
if (isCapital(inputString[i]) && !isCapital(inputString[i + 1])) {
begin = i + 1;
break;
}
}
inputString = GetSubstring(inputString, begin, length);
unsigned int end = 0;
for(int i = 0; i <= length - 1; i++) {
if (!isCapital(inputString[i]) && isCapital(inputString[i + 1])) {
end = i + 1;
break;
}
}
Substring result = { GetSubstring(inputString, 0, end), begin, begin + end, end };
return result;
}
// найти все подстроки в строке, выделенные латинскими заглавными символами
SubstringCollection FindAllSubstrings(char *inputString, unsigned int length) {
SubstringCollection collection;
collection.Collection = malloc(sizeof(Substring) * 1);
collection.Count = 0;
do {
Substring foundSubstring = FindSubstring(inputString, length);
if (foundSubstring.Length == 0) {
break;
}
else {
collection.Collection = realloc(collection.Collection, sizeof(Substring) * (collection.Count + 1));
collection.Collection[collection.Count] = foundSubstring;
inputString = GetSubstring(inputString, foundSubstring.End, length);
length = length - foundSubstring.End;
collection.Count++;
}
} while (1);
return collection;
}
// простой нормальный человеческий метод для чтения из консоли,
// чтобы не связываться с этим отвратительно мерзким scanf работающим через ...
char* ReadLine(unsigned int bufferSize) {
char* buffer = calloc(bufferSize, sizeof(char));
char symbol;
unsigned int counter = 0;
do {
symbol = getchar();
if (symbol == '\n' || counter >= bufferSize) {
break;
} else {
buffer[counter] = symbol;
counter++;
}
} while (1);
return buffer;
}
int main()
{
do {
unsigned inputLength = 4096;
char *inputLine;
SubstringCollection collection;
printf("\nEnter line:\n");
inputLine = calloc(inputLength, sizeof(char));
inputLine = ReadLine(inputLength);
if (inputLine[0] == '\0')
break;
// ТЕСТОВАЯ СТРОКА: BEGIN usual text END BEGIN text with parentheses{ END BEGIN textwith russian at the endрусский текстEND
collection = FindAllSubstrings(inputLine, inputLength);
// создаем список для того, чтобы отметить элементы, которые мы будем удалять
_Bool *RemoveItemList = calloc(collection.Count, sizeof(_Bool));
for (int i = 0; i != collection.Count; i++) {
if (CheckForParentheses(collection.Collection[i].String, collection.Collection[i].Length) == 1)
RemoveItemList[i] = 1;
}
// теперь после того, как мы определили подстроки, в которых есть скобки, мы удаляем их
for (int i = collection.Count; i != 0; i--) {
if (RemoveItemList[i] == 1)
collection = RemoveFromCollection(collection, i);
}
// теперь пробегаемся по остаткам коллекции и удаляем элементы, у которых на конце есть русские символы, если они есть еще где-то, то они не удалятся
for (int i = 0; i != collection.Count; i++) {
collection.Collection[i] = RemoveRussianSymbolsAtTheEnd(collection.Collection[i].String, collection.Collection[i].Length);
}
// выводим этот хлам
for (int i = 0; i != collection.Count; i++) {
printf("%d). \"%s\"\n", i+1, collection.Collection[i].String);
}
} while (1);
return 0;
}