Есть программа, которая хорошо работает с небольшим объемом текста
Мне нужно было сделать так, чтобы, когда происходило превышение по памяти, программа удаляла часть текста из массива, сдвигая его.
Программа: 1я строка - то что ищем Далее текст в котором ищем
Проблема заключается в левых числах при разбиении текста
Очень надеюсь на вашу помощь!
// 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;
}
Продвижение своими сайтами как стратегия роста и независимости