Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Алгоритм формирования списка верных слов


Автор: Insert 12.4.2007, 22:58
Здравствуйте, пишу текстовый редактор, вот сделал проверку орфографии, но осталось сделать последнюю фичу контекстное меню с выпадающим списком возможных замен, может у кого нить есть какие то наработки в этом направлении или ссылку на материалы по данной теме

Автор: Sunvas 13.4.2007, 12:00
Цитата(Insert @  12.4.2007,  22:58 Найти цитируемый пост)
вот сделал проверку орфографии

Как же ты ее сделал если у тебя нет списка правильных слов?

Автор: Insert 13.4.2007, 12:24
 smile  щас только проверяется слово на наличие его в словаре, если нету его там, то подчёркивается как в ворде, но список со словами, на которые можно заменить это неправильное слово я как раз и не могу сгенерировать, есть функции на проверку слова в словаре и все, я пробовал изменять по букве в непр слове и проверять на наличие, если есть то в список, но это неправильно, т к может быть разным кол - во букв и приставки и тд и тп. Так что до полного завершения работы с орфографией не хватает только этого. smile 

Автор: MaXL 14.4.2007, 01:58
Insert, привет. Я как раз тоже сейчас этим занимаюсь, нашёл что такое можно реализовать с помощью расстояния Левеннштейна.
Вот ссылка по теме:
http://itman.narod.ru/source/source.html

Автор: Insert 14.4.2007, 08:55
MaXL, так нада посмотреть, если будут какие то результаты у меня я тут отпишусь.

Автор: Sardar 14.4.2007, 11:56
Собери в словарь в http://en.wikipedia.org/wiki/Trie, затем ищи вычисляя расстояние Левенштейна. В идеале разным операциям можно дать разные веса, нпаример ошибкам синхронизации можно дать вес выше чем остальным. Сортируешь список по расстоянию, берёшь первые 5.

Автор: Святогор 14.4.2007, 12:54
MaXL, 
Ну а вообще есть ещё инфа по-поводу проверки орфографии ? Мне для англ. языка нужно.

Автор: MaXL 14.4.2007, 15:11
Святогор, помоему реализация этого алгоритма не операется на конкретные языки(русский, китайский, немецкий, английский...). Просто какие ты ему входные данные подкинешь с таким он и будет работать. Я ещё пока с этим алгоритмом не занимался, так в данный момент перекинулся на кое - что другое, но вскоре к этому опять вернусь. 
Вот ещё ссылка: http://www.levenshtein.net/.
P.S. да и как мне кажется по этому вопросу можно обратиться в раздел "Алгоритмы" этого форума, уверен что помогут.

Автор: Insert 16.4.2007, 23:44
Так так есть кое какие результаты, вот нашел две реализации неточного поиска, один вычисляет расстояние Левинштейна, другой возвращает в % похожесть одной строки на другую(взят с vingard)

Расстояние Левинштейна:
Код


var
  const cuthalf = 100;
  buf: array [0..199] of integer;

function min3(a, b, c: integer): integer;
begin
  Result := a;
  if b < Result then Result := b;
  if c < Result then Result := c;
end;

function Levenstain(s, t: string): integer;
var i, j, m, n: integer;
    cost: integer;
    flip: boolean;
begin
  s := copy(s, 1, cuthalf - 1);
  t := copy(t, 1, cuthalf - 1);
  m := length(s);
  n := length(t);
  if m = 0 then Result := n
  else if n = 0 then Result := m
  else begin
    flip := false;
    for i := 0 to n do buf[i] := i;
    for i := 1 to m do begin
      if flip then buf[0] := i
      else buf[cuthalf] := i;
      for j := 1 to n do begin
        if s[i] = t[j] then cost := 0
        else cost := 1;
        if flip then
          buf[j] := min3((buf[cuthalf + j] + 1),
                         (buf[j - 1] + 1),
                         (buf[cuthalf + j - 1] + cost))
        else
          buf[cuthalf + j] := min3((buf[j] + 1),
                                   (buf[cuthalf + j - 1] + 1),
                                   (buf[j - 1] + cost));
      end;
      flip := not flip;
    end;
    if flip then Result := buf[cuthalf + n]
    else Result := buf[n];
  end;

end;



Вот который возвращает похожесть в процентах:

Код



function testpercent(s1,s2: string): double;
var i,j,max: longint;
chto_ishem, v_chem,test: string;
begin
max:=0;
   if Length(s1)>Length(s2) then
   begin
   chto_ishem:=s2;
   v_chem:=s1;
   end else
   begin
    chto_ishem:=s1;
   v_chem:=s2;
   end;
   for i:=1 to Length(chto_ishem) do
   for j:=Length(chto_ishem)+1-i downto i do
    begin
   test:=copy( chto_ishem,i,j);
   if (Pos(
   test
   ,v_chem)>0) then
   if (max<Length(test))
   then
   max:= Length(test);
   end;
   Result:=max*100/Length(v_chem);
end;



Так вот
Sardar, писал что неплохо было бы сформировать из словаря префиксное дерево, можно об этом поподробнее... кстати в моем случае все содержимое словаря недоступно, есть только функция на проверку наличия слова в словаре, чувствую этого будет маловато, может есть ещё варианты куда двигаться?

Автор: Insert 17.4.2007, 09:38
В моем словаре 180 000 оснований слов, если их перебирать и для каждого вычислять расстояние Левинштейна, то это будет очень долго, есть какие нить варианты ускорить поиск. Как я понял, если искать по префиксному дереву, то будет намного быстрее, но как весь словарь забить в него?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)