Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // STD и стандартные библиотеки
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #include <iostream>
- #include <cctype>
- #include <cstring>
- struct Word {
- char Text[50];
- unsigned int pos;
- unsigned int line;
- };
- // Структура списка слов
- struct WordList {
- unsigned int count;
- struct Word * Words;
- };
- const int WordLength = 75; // Максимальная длина одного слова
- const unsigned int RAMLimit = 1000;//2147483648; // Ограничение по памяти
- const double RAMreserv = 5; // Сколько RAM зарезервированно (в %)
- unsigned int x = 0;
- unsigned int y = 1;
- // Сигнатуры функций
- unsigned int GetSubStr(struct WordList * WL);
- bool GetTextPrt(struct WordList * WL, unsigned int AvMemory);
- void Z_FUC(struct WordList * WL, unsigned int SubStrCount);
- void Cutter(struct WordList * WL, unsigned int SubStrCount);
- // Основной цикл
- int main() {
- // Переменные
- struct WordList MainStr;
- unsigned int AvMemory = (unsigned int)(RAMLimit * (1-(RAMreserv / 100)));
- unsigned int SubStrCount;
- bool exitkey = true;
- // Инициализация MainStr
- MainStr.count = 0;
- MainStr.Words = (struct Word*)malloc(15*sizeof(struct Word));
- // Ввод подстроки + резерв места под уникальное слово
- AvMemory -= GetSubStr(&MainStr);
- // Сохранить длину постоянной части
- SubStrCount = MainStr.count;
- // Считываем и обрабатываем дальнейшие строки
- while (exitkey){
- // Cчитываем допустимый объем
- exitkey = GetTextPrt(&MainStr, AvMemory/2);
- // Включаем Z-функцию и выводим результат
- Z_FUC(&MainStr, SubStrCount);
- // Обрезка строки
- Cutter(&MainStr, SubStrCount);
- }
- free(MainStr.Words);
- return 0;
- }
- // Заполнение подстроки
- unsigned int GetSubStr(struct WordList * WL) {
- // Переменные
- char Char;
- bool exitkey = false;
- unsigned int i = 0;
- unsigned int freeblocks = 0;
- while (!exitkey) {
- // Cчитывание символа
- Char = toupper(getchar_unlocked());
- // Если нет места
- if (freeblocks == 0) {
- freeblocks = (unsigned int)(WL->count * 1.25 + 1);
- WL->Words = (struct Word *)realloc(WL->Words, (WL->count + freeblocks) * sizeof(struct Word));
- }
- // Если символ - добавляем
- if (((Char >= 'A') && (Char <= 'Z')) || ((Char >= '0') && (Char <= '9'))) {
- WL->Words[WL->count].Text[i] = Char;
- i++;
- }
- else
- // Если символ - пробел
- if (((Char == ' ') || (Char == 't')) && (i > 0)) {
- freeblocks--;
- WL->Words[WL->count].Text[i] = 0;
- i = 0;
- WL->count++;
- }
- // Если символ - переход на новую строку
- if (Char == 'n') {
- if (i > 0) {
- freeblocks--;
- WL->Words[WL->count].Text[i] = 0;
- i = 0;
- WL->count++;
- }
- exitkey = true;
- }
- else
- // Если это конец ввода
- if (Char == EOF) {
- if (i > 0) {
- freeblocks--;
- WL->Words[WL->count].Text[i] = 0;
- i = 0;
- WL->count++;
- }
- exitkey = true;
- }
- }
- WL->Words = (struct Word *)realloc(WL->Words, (WL->count + 1) * sizeof(struct Word));
- WL->count++;
- // Добавить уникальное слово
- sprintf(WL->Words[WL->count - 1].Text, "%s", "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
- WL->Words[WL->count - 1].line = 0;
- WL->Words[WL->count - 1].pos = 0;
- return (WL->count * sizeof(struct Word));
- }
- // Заполнение остальных строк
- bool GetTextPrt(struct WordList * WL, unsigned int AvMemory) {
- // Переменные
- char Char;
- bool exitkey = false;
- unsigned int i = 0;
- unsigned int freeblocks = 0;
- while (!exitkey){
- // Cчитывание символа
- Char = toupper(getchar_unlocked());
- // Если нет места
- if (freeblocks == 0) {
- freeblocks = (unsigned int)(WL->count * 1.25 + 1);
- WL->Words = (struct Word *)realloc(WL->Words, (WL->count+freeblocks)*sizeof(struct Word));
- }
- // Доп. определение EOF
- if (Char == '@') Char = EOF;
- // Если символ - добавляем
- if (((Char >= 'A') && (Char <= 'Z')) || ((Char >= '0') && (Char <= '9'))) {
- WL->Words[WL->count].Text[i] = Char;
- i++;
- }
- else
- // Если память закончилась
- if (AvMemory < WL->count * sizeof(struct Word)) Char = EOF; else
- // Если символ - пробел
- if (((Char == ' ')|| (Char == 't'))&&(i>0)){
- freeblocks--;
- WL->Words[WL->count].Text[i] = 0;
- i = 0;
- x++;
- WL->Words[WL->count].pos = x;
- WL->Words[WL->count].line = y;
- WL->count++;
- }
- // Если символ - переход на новую строку
- if (Char == 'n') {
- if (i > 0) {
- freeblocks--;
- WL->Words[WL->count].Text[i] = 0;
- i = 0;
- x++;
- WL->Words[WL->count].pos = x;
- WL->Words[WL->count].line = y;
- WL->count++;
- }
- y++;
- x = 0;
- } else
- // Если это конец ввода
- if (Char == EOF){
- if (i > 0) {
- freeblocks--;
- WL->Words[WL->count].Text[i] = 0;
- i = 0;
- x++;
- WL->Words[WL->count].pos = x;
- WL->Words[WL->count].line = y;
- WL->count++;
- }
- exitkey = true;
- }
- }
- WL->Words = (struct Word *)realloc(WL->Words, (WL->count) * sizeof(struct Word));
- return (AvMemory < WL->count * sizeof(struct Word));
- }
- // Функция минимума (служебная)
- unsigned int GetMin(unsigned int l, unsigned int r) {
- if (l <= r) return l; else return r;
- }
- // Сравнить строки (служебная)
- bool smp(const char *str1, const char *str2) {
- return (strcmp(str1, str2) == 0);
- }
- // Запуск Z функции и вывод результата
- void Z_FUC(struct WordList * WL, unsigned int SubStrCount) {
- // Переменные
- unsigned int* DStr;
- unsigned int i; // Тикер для циклов
- unsigned int left = 0; // Необходимо для Z-function
- unsigned int right = 0; // Необходимо для Z-function
- /* Z-функция */
- // Инициализация
- DStr = (unsigned int*)malloc(WL->count*sizeof(unsigned int));
- for (i = 0; i < WL->count; i++) DStr[i] = 0;
- // Работа шайтан машины
- for (i = 1; i < WL->count; ++i) {
- if (i <= right) DStr[i] = GetMin(right - i + 1, DStr[i - left]);
- while (((i + DStr[i]) < WL->count) && (smp(WL->Words[DStr[i]].Text, WL->Words[i + DStr[i]].Text))) {
- ++(DStr[i]);
- }
- if (i + DStr[i] - 1 > right) {
- left = i;
- right = i + DStr[i] - 1;
- }
- }
- // Вывод ответа
- for (i = 0; i < (WL->count - SubStrCount); i++){
- if (DStr[i + SubStrCount] == SubStrCount - 1) {
- printf("%u%s%d%c", WL->Words[i + SubStrCount].line, ", ", WL->Words[i + SubStrCount].pos, 'n');
- }
- }
- }
- void Cutter(struct WordList * WL, unsigned int SubStrCount) {
- // Переменные
- unsigned int i;
- for (i = 0; i < SubStrCount-2; i++) {
- WL->Words[SubStrCount + i].line = WL->Words[WL->count - (SubStrCount - 2) + i].line;
- WL->Words[SubStrCount + i].pos = WL->Words[WL->count - (SubStrCount - 2) + i].pos;
- sprintf(WL->Words[SubStrCount + i].Text, "%s", WL->Words[WL->count - (SubStrCount - 2) + i].Text);
- }
- WL->Words = (struct Word*)realloc(WL->Words, (2*SubStrCount-1)*sizeof(struct Word));
- WL->count = 2 * SubStrCount - 2;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement