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
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;
|
|
}
|