fork(9) download
  1. program AmigaVirtual;
  2.  
  3. {$MODE OBJFPC}
  4.  
  5. const
  6. threshold = 0.65; //порог обучения/ответа
  7. defsyl = 4; //длина слога по умолчанию
  8.  
  9. type
  10. TDB = array of string; //база данных
  11.  
  12. var
  13. DB: TDB;
  14.  
  15. //Вычисление совпадений строк, результат в диапазоне 0.0 .. 1.0
  16. function CalcSim(A, B: string; syl: integer = defsyl): real;
  17.  
  18. //Входит ли строка B в строку S?
  19. function IsStrInStr(B, S: string): boolean;
  20. var
  21. i: integer;
  22. begin
  23. IsStrInStr := false;
  24. for i := 1 to Length(S) - Length(B) + 1 do
  25. if B = Copy(S, i, Length(B)) then
  26. begin
  27. IsStrInStr := true;
  28. exit;
  29. end;
  30. end;
  31.  
  32. //Число слогов в строке
  33. function SylCount(S: string; syl: integer): integer;
  34. begin
  35. SylCount := Length(S) - syl + 1;
  36. end;
  37.  
  38. var
  39. Match: integer = 0;
  40. i: integer;
  41. C, D: string;
  42. begin
  43. //Если строки и так одинаковые, выходим
  44. if A = B then
  45. begin
  46. CalcSim := 1;
  47. exit;
  48. end;
  49.  
  50. //Определяем короткую (D) и длинную (C) строки
  51. if Length(A) > Length(B) then
  52. begin C := A; D := B; end else
  53. begin C := B; D := A; end;
  54.  
  55. Write(Length(D), ' ', Length(C), ' - ');
  56.  
  57. //Если наименьшая строка меньше длины слога
  58. if Length(D) < syl then
  59. begin
  60. C := C + Copy(C, 1, Length(D) - 1);
  61. if IsStrInStr(D, C) then Match := 1;
  62. CalcSim := Match / SylCount(C, Length(D));
  63. exit;
  64. end;
  65.  
  66. //Добавляем символы из начала строк в их конец
  67. C := C + Copy(C, 1, syl - 1);
  68. D := D + Copy(D, 1, syl - 1);
  69.  
  70. //Подсчитываем количество совпадающих слогов
  71. for i := 1 to Length(C) - syl + 1 do
  72. if IsStrInStr(Copy(C, i, syl), D) then
  73. inc(Match);
  74.  
  75. //Вычисляем процент совпадений
  76. CalcSim := Match / SylCount(C, syl) ;
  77. end;
  78.  
  79. //Загружаем БД из файла
  80. function LoadDB: TDB;
  81. var
  82. buf: TDB;
  83. begin
  84. while not eof do
  85. begin
  86. SetLength(buf, Length(buf)+1);
  87. Readln(buf[Length(buf)-1]);
  88. end;
  89. LoadDB := buf;
  90. end;
  91.  
  92. //Ищем в БД максимально совпадающую с LastSent строку
  93. //и выдаём следующую за ней строку
  94. function NextSentence(var DB: TDB; LastSent: string; var MS: real): string;
  95. var
  96. Sim, MaxSim: real;
  97. i: integer;
  98. begin
  99. MaxSim := 0;
  100. for i := 0 to Length(DB) - 2 do
  101. begin
  102. Sim := CalcSim(DB[i], LastSent);
  103. //Если нашли строку, которая совпадает больше
  104. if Sim > MaxSim then
  105. begin
  106. MaxSim := Sim;
  107. NextSentence := DB[i + 1];
  108. end;
  109. end;
  110. //Если процент совпадения меньше порога,
  111. //тогда записываем строку в БД
  112. if MaxSim < threshold then
  113. begin
  114. NextSentence := '[SYSTEM] Нет ответа, фраза запомнена';
  115. SetLength(DB, Length(DB) + 1);
  116. DB[Length(DB) - 1] := LastSent;
  117. end;
  118. MS := MaxSim;
  119. end;
  120.  
  121. //Сравниваем две строки между собой
  122. //и выводим результат на экран
  123. procedure SS(A, B: string; syl: integer = defsyl);
  124. begin
  125. Writeln(A + ':' + B + ' - ', (CalcSim(A, B, syl) * 100):3:2, '%');
  126. end;
  127.  
  128. //Имитация отправки пользователем строки
  129. procedure Say(S: string);
  130. var
  131. Sim: real;
  132. begin
  133. Writeln('Вы: ', S);
  134. Writeln('AV: ', NextSentence(DB, S, Sim), ' (', (Sim * 100):3:2, '%)');
  135. end;
  136.  
  137. var
  138. i: integer;
  139.  
  140. begin
  141. DB := LoadDB;
  142. Say('Как дила?');
  143. Say('Ну дык чо, о чём побазарим?');
  144. Say('Да за жизнь нашу блатную');
  145. Say('О чём побазарим?');
  146. Say('Побазарим о чём?');
  147. Say('Скажи, что такое молоко?');
  148. Say('Молоко - это напиток.');
  149. Say('Скажи, что такое малако?');
  150. Say('Скажи, что такое Колыма?');
  151. Say('Что такое Колыма?');
  152. Writeln;
  153. //Распечатываем БД
  154. Writeln('---- DB dump: ----');
  155. for i := 0 to Length(DB) - 1 do
  156. Writeln(DB[i]);
  157. Writeln;
  158. SS('abcd', 'fghj');
  159. SS('abcd', 'nm');
  160. SS('abcd', 'abfg');
  161. SS('abcd', 'abce');
  162. SS('abcd', 'abcd');
  163. SS('abed', 'abcd');
  164. SS('abcde', 'abcfr');
  165. SS('abcdefgh', 'abcd');
  166. SS('abcdefgh', 'cd');
  167. SS('abcd', 'abcde');
  168. SS('abcdef', 'abc');
  169. SS('abcd', 'cdab');
  170. SS('abcdef', 'abefcd');
  171. SS('молоко', 'малако');
  172. SS('молоко', 'млко');
  173. SS('молоко', 'Колыма');
  174. SS('абвгдеёжзи', 'абв', 4);
  175. SS('абвгдеёжzи', 'абв', 4);
  176. SS('abcdefghij', 'abc', 4);
  177. SS('абвгдеёжзи', 'аб', 4);
  178. SS('абвгдеёжзи', 'а', 4);
  179. SS('абвгдеёжзи', '', 4);
  180. end.
Success #stdin #stdout 0s 280KB
stdin
Привет
Приветик
Как дела?
У меня всё хорошо, а у тебя?
У меня тоже всё нормально.
stdout
Вы: Как дила?
AV: 12 16 - 16 16 - 16 16 - 16 48 - У меня всё хорошо, а у тебя? (75.00%)
Вы: Ну дык чо, о чём побазарим?
AV: 12 47 - 16 47 - 16 47 - 47 48 - [SYSTEM] Нет ответа, фраза запомнена (4.26%)
Вы: Да за жизнь нашу блатную
AV: 12 44 - 16 44 - 16 44 - 44 48 - 44 47 - [SYSTEM] Нет ответа, фраза запомнена (2.27%)
Вы: О чём побазарим?
AV: 12 29 - 16 29 - 16 29 - 29 48 - 29 47 - 29 47 - [SYSTEM] Нет ответа, фраза запомнена (53.19%)
Вы: Побазарим о чём?
AV: 12 29 - 16 29 - 16 29 - 29 48 - 29 47 - 29 47 - 29 44 - [SYSTEM] Нет ответа, фраза запомнена (46.81%)
Вы: Скажи, что такое молоко?
AV: 12 43 - 16 43 - 16 43 - 43 48 - 43 47 - 43 47 - 43 44 - 29 43 - [SYSTEM] Нет ответа, фраза запомнена (8.51%)
Вы: Молоко - это напиток.
AV: 12 37 - 16 37 - 16 37 - 37 48 - 37 47 - 37 47 - 37 44 - 29 37 - 29 37 - [SYSTEM] Нет ответа, фраза запомнена (6.38%)
Вы: Скажи, что такое малако?
AV: 12 43 - 16 43 - 16 43 - 43 48 - 43 47 - 43 47 - 43 44 - 29 43 - 29 43 - 43 43 - Молоко - это напиток. (86.05%)
Вы: Скажи, что такое Колыма?
AV: 12 43 - 16 43 - 16 43 - 43 48 - 43 47 - 43 47 - 43 44 - 29 43 - 29 43 - 43 43 - Молоко - это напиток. (69.77%)
Вы: Что такое Колыма?
AV: 12 31 - 16 31 - 16 31 - 31 48 - 31 47 - 31 47 - 31 44 - 29 31 - 29 31 - 31 43 - [SYSTEM] Нет ответа, фраза запомнена (37.21%)

---- DB dump: ----
Привет
Приветик
Как дела?
У меня всё хорошо, а у тебя?
У меня тоже всё нормально.
Ну дык чо, о чём побазарим?
Да за жизнь нашу блатную
О чём побазарим?
Побазарим о чём?
Скажи, что такое молоко?
Молоко - это напиток.
Что такое Колыма?

abcd:fghj - 4 4 - 0.00%
abcd:nm - 2 4 - 0.00%
abcd:abfg - 4 4 - 0.00%
abcd:abce - 4 4 - 0.00%
abcd:abcd - 100.00%
abed:abcd - 4 4 - 0.00%
abcde:abcfr - 5 5 - 0.00%
abcdefgh:abcd - 4 8 - 12.50%
abcdefgh:cd - 2 8 - 12.50%
abcd:abcde - 4 5 - 20.00%
abcdef:abc - 3 6 - 16.67%
abcd:cdab - 4 4 - 100.00%
abcdef:abefcd - 6 6 - 0.00%
молоко:малако - 12 12 - 33.33%
молоко:млко - 8 12 - 33.33%
молоко:Колыма - 12 12 - 8.33%
абвгдеёжзи:абв - 6 20 - 20.00%
абвгдеёжzи:абв - 6 19 - 21.05%
abcdefghij:abc - 3 10 - 10.00%
абвгдеёжзи:аб - 4 20 - 10.00%
абвгдеёжзи:а - 2 20 - 5.00%
абвгдеёжзи: - 0 20 - 4.76%