Advertisement
Guest User

Untitled

a guest
Jun 24th, 2019
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.32 KB | None | 0 0
  1. // STD и стандартные библиотеки
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stdbool.h>
  5. #include <iostream>
  6. #include <cctype>
  7. #include <cstring>
  8.  
  9. struct Word {
  10. char Text[50];
  11. unsigned int pos;
  12. unsigned int line;
  13. };
  14.  
  15. // Структура списка слов
  16. struct WordList {
  17. unsigned int count;
  18. struct Word * Words;
  19. };
  20.  
  21.  
  22. const int WordLength = 75; // Максимальная длина одного слова
  23. const unsigned int RAMLimit = 1000;//2147483648; // Ограничение по памяти
  24. const double RAMreserv = 5; // Сколько RAM зарезервированно (в %)
  25.  
  26. unsigned int x = 0;
  27. unsigned int y = 1;
  28.  
  29.  
  30. // Сигнатуры функций
  31. unsigned int GetSubStr(struct WordList * WL);
  32. bool GetTextPrt(struct WordList * WL, unsigned int AvMemory);
  33. void Z_FUC(struct WordList * WL, unsigned int SubStrCount);
  34. void Cutter(struct WordList * WL, unsigned int SubStrCount);
  35.  
  36.  
  37. // Основной цикл
  38. int main() {
  39. // Переменные
  40. struct WordList MainStr;
  41. unsigned int AvMemory = (unsigned int)(RAMLimit * (1-(RAMreserv / 100)));
  42. unsigned int SubStrCount;
  43. bool exitkey = true;
  44.  
  45. // Инициализация MainStr
  46. MainStr.count = 0;
  47. MainStr.Words = (struct Word*)malloc(15*sizeof(struct Word));
  48.  
  49. // Ввод подстроки + резерв места под уникальное слово
  50. AvMemory -= GetSubStr(&MainStr);
  51.  
  52. // Сохранить длину постоянной части
  53. SubStrCount = MainStr.count;
  54.  
  55. // Считываем и обрабатываем дальнейшие строки
  56. while (exitkey){
  57. // Cчитываем допустимый объем
  58. exitkey = GetTextPrt(&MainStr, AvMemory/2);
  59.  
  60. // Включаем Z-функцию и выводим результат
  61. Z_FUC(&MainStr, SubStrCount);
  62.  
  63. // Обрезка строки
  64. Cutter(&MainStr, SubStrCount);
  65. }
  66.  
  67. free(MainStr.Words);
  68.  
  69. return 0;
  70. }
  71.  
  72.  
  73. // Заполнение подстроки
  74. unsigned int GetSubStr(struct WordList * WL) {
  75. // Переменные
  76. char Char;
  77. bool exitkey = false;
  78. unsigned int i = 0;
  79. unsigned int freeblocks = 0;
  80.  
  81. while (!exitkey) {
  82. // Cчитывание символа
  83. Char = toupper(getchar_unlocked());
  84. // Если нет места
  85. if (freeblocks == 0) {
  86. freeblocks = (unsigned int)(WL->count * 1.25 + 1);
  87. WL->Words = (struct Word *)realloc(WL->Words, (WL->count + freeblocks) * sizeof(struct Word));
  88. }
  89.  
  90. // Если символ - добавляем
  91. if (((Char >= 'A') && (Char <= 'Z')) || ((Char >= '0') && (Char <= '9'))) {
  92. WL->Words[WL->count].Text[i] = Char;
  93. i++;
  94. }
  95. else
  96.  
  97. // Если символ - пробел
  98. if (((Char == ' ') || (Char == 't')) && (i > 0)) {
  99. freeblocks--;
  100. WL->Words[WL->count].Text[i] = 0;
  101. i = 0;
  102. WL->count++;
  103. }
  104.  
  105. // Если символ - переход на новую строку
  106. if (Char == 'n') {
  107. if (i > 0) {
  108. freeblocks--;
  109. WL->Words[WL->count].Text[i] = 0;
  110. i = 0;
  111. WL->count++;
  112. }
  113. exitkey = true;
  114. }
  115. else
  116.  
  117. // Если это конец ввода
  118. if (Char == EOF) {
  119. if (i > 0) {
  120. freeblocks--;
  121. WL->Words[WL->count].Text[i] = 0;
  122. i = 0;
  123. WL->count++;
  124. }
  125. exitkey = true;
  126. }
  127.  
  128. }
  129. WL->Words = (struct Word *)realloc(WL->Words, (WL->count + 1) * sizeof(struct Word));
  130. WL->count++;
  131. // Добавить уникальное слово
  132. sprintf(WL->Words[WL->count - 1].Text, "%s", "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
  133. WL->Words[WL->count - 1].line = 0;
  134. WL->Words[WL->count - 1].pos = 0;
  135.  
  136.  
  137.  
  138. return (WL->count * sizeof(struct Word));
  139.  
  140. }
  141.  
  142.  
  143. // Заполнение остальных строк
  144. bool GetTextPrt(struct WordList * WL, unsigned int AvMemory) {
  145. // Переменные
  146. char Char;
  147. bool exitkey = false;
  148. unsigned int i = 0;
  149. unsigned int freeblocks = 0;
  150.  
  151. while (!exitkey){
  152. // Cчитывание символа
  153. Char = toupper(getchar_unlocked());
  154. // Если нет места
  155. if (freeblocks == 0) {
  156. freeblocks = (unsigned int)(WL->count * 1.25 + 1);
  157. WL->Words = (struct Word *)realloc(WL->Words, (WL->count+freeblocks)*sizeof(struct Word));
  158. }
  159.  
  160. // Доп. определение EOF
  161. if (Char == '@') Char = EOF;
  162.  
  163. // Если символ - добавляем
  164. if (((Char >= 'A') && (Char <= 'Z')) || ((Char >= '0') && (Char <= '9'))) {
  165. WL->Words[WL->count].Text[i] = Char;
  166. i++;
  167. }
  168. else
  169.  
  170. // Если память закончилась
  171. if (AvMemory < WL->count * sizeof(struct Word)) Char = EOF; else
  172.  
  173. // Если символ - пробел
  174. if (((Char == ' ')|| (Char == 't'))&&(i>0)){
  175. freeblocks--;
  176. WL->Words[WL->count].Text[i] = 0;
  177. i = 0;
  178. x++;
  179. WL->Words[WL->count].pos = x;
  180. WL->Words[WL->count].line = y;
  181. WL->count++;
  182. }
  183.  
  184. // Если символ - переход на новую строку
  185. if (Char == 'n') {
  186. if (i > 0) {
  187. freeblocks--;
  188. WL->Words[WL->count].Text[i] = 0;
  189. i = 0;
  190. x++;
  191. WL->Words[WL->count].pos = x;
  192. WL->Words[WL->count].line = y;
  193. WL->count++;
  194. }
  195. y++;
  196. x = 0;
  197. } else
  198.  
  199. // Если это конец ввода
  200. if (Char == EOF){
  201. if (i > 0) {
  202. freeblocks--;
  203. WL->Words[WL->count].Text[i] = 0;
  204. i = 0;
  205. x++;
  206. WL->Words[WL->count].pos = x;
  207. WL->Words[WL->count].line = y;
  208. WL->count++;
  209. }
  210. exitkey = true;
  211. }
  212.  
  213. }
  214. WL->Words = (struct Word *)realloc(WL->Words, (WL->count) * sizeof(struct Word));
  215.  
  216. return (AvMemory < WL->count * sizeof(struct Word));
  217. }
  218.  
  219.  
  220. // Функция минимума (служебная)
  221. unsigned int GetMin(unsigned int l, unsigned int r) {
  222. if (l <= r) return l; else return r;
  223. }
  224.  
  225. // Сравнить строки (служебная)
  226. bool smp(const char *str1, const char *str2) {
  227. return (strcmp(str1, str2) == 0);
  228. }
  229.  
  230. // Запуск Z функции и вывод результата
  231. void Z_FUC(struct WordList * WL, unsigned int SubStrCount) {
  232. // Переменные
  233. unsigned int* DStr;
  234. unsigned int i; // Тикер для циклов
  235. unsigned int left = 0; // Необходимо для Z-function
  236. unsigned int right = 0; // Необходимо для Z-function
  237.  
  238.  
  239. /* Z-функция */
  240.  
  241. // Инициализация
  242. DStr = (unsigned int*)malloc(WL->count*sizeof(unsigned int));
  243. for (i = 0; i < WL->count; i++) DStr[i] = 0;
  244.  
  245. // Работа шайтан машины
  246. for (i = 1; i < WL->count; ++i) {
  247.  
  248. if (i <= right) DStr[i] = GetMin(right - i + 1, DStr[i - left]);
  249.  
  250. while (((i + DStr[i]) < WL->count) && (smp(WL->Words[DStr[i]].Text, WL->Words[i + DStr[i]].Text))) {
  251. ++(DStr[i]);
  252. }
  253.  
  254. if (i + DStr[i] - 1 > right) {
  255. left = i;
  256. right = i + DStr[i] - 1;
  257. }
  258. }
  259.  
  260. // Вывод ответа
  261. for (i = 0; i < (WL->count - SubStrCount); i++){
  262. if (DStr[i + SubStrCount] == SubStrCount - 1) {
  263. printf("%u%s%d%c", WL->Words[i + SubStrCount].line, ", ", WL->Words[i + SubStrCount].pos, 'n');
  264. }
  265. }
  266.  
  267. }
  268.  
  269. void Cutter(struct WordList * WL, unsigned int SubStrCount) {
  270. // Переменные
  271. unsigned int i;
  272. for (i = 0; i < SubStrCount-2; i++) {
  273. WL->Words[SubStrCount + i].line = WL->Words[WL->count - (SubStrCount - 2) + i].line;
  274. WL->Words[SubStrCount + i].pos = WL->Words[WL->count - (SubStrCount - 2) + i].pos;
  275. sprintf(WL->Words[SubStrCount + i].Text, "%s", WL->Words[WL->count - (SubStrCount - 2) + i].Text);
  276. }
  277. WL->Words = (struct Word*)realloc(WL->Words, (2*SubStrCount-1)*sizeof(struct Word));
  278. WL->count = 2 * SubStrCount - 2;
  279. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement