Słownik ortograficzny

0

Jak pewnie kilka osób zauważyło piszę edytor textu. Chciałbym dodać do niego opcję sprawdzania pisowni ( nie korzystając z żadnego gotowego komponentu!) Chodzi o to, żeby słownik znajdował się w pliku textowym, a po wpisaniu textu do RE i postawieniu spacji lub entera program sprawdzałby, czy wyraz znajduje sie w słowniku. Jeżeli nie to podkreślałby go na czerwono :)
Da się coś takiego zrobić ?? I oczywiście jak :D [hurra]

0

Pewnie że się da.... trzeba tylko:

  1. Znaleźć słownik polski w pliku tekstowym - gdzieś taki widziałem - koło 10 mb...

  2. Napisać procedurę sprawdzającą z plikiem

  3. Włączyć program :)

Oczywiście samo załadowanie słownika zajmie jakieś 10 sekund... jeśli w ogole sie wszystko nie zawiesi... że nie wspomne o sprawdzaniu - każde sprawdzenie zajmie kilka sekund... czyli ... LIPA

0

Jak się tak do tego podejdzie, to rzeczywiście lipa.
Proponuję wpisać w wyszukiwarce Uniwersalna Struktura Słownikowa. Już Vogel pisał jak to zrobić.

0

Słownik jest gotowy pod adresem http://www.kurnik.pl/slownik/growy/ - po rozpakowaniu około 30Mb. Jak będziesz go wgrywał za pomocą ReadBuffer, to u mnie zajmuje to jakieś 5.5 sekundy, to oczywiście zależy od szybkości sprzętu, ja mam Celerona 366. Jest oczywiście taki makament, że sprawdzanie będzie trwało w nieskończoność, bo musisz zastosować pętlę, która będzie porównywała każdy wyraz ze słownika z ostatnim wyrazem z Memo. I w tym właśnie miejscu trzeba wymyśleć coś innego, bo taka operacja zajmuje około 30-40 sekund... A jak ci się uda to jeszcze musisz pobrać pozycję (w pixelach) błędnie napisanego wyrazu w Memo i narysować na tym Memo linię pod tym wyrazem. Powodzenia.

//DOPISANE
Z ciekawości wpisałem sobie tą "uniwersalną strukturę słownikową", wyświetliło mi tylko jedną stronę. Przejrzałem z grubsza, ale się przestraszyłem wzorów, jakie tam widziałem...

//DOPISANE2
link : http://www.orca2.mila.edu.pl/~astajniak/indexalg.htm

0

Ta wyszukiwarka jest dobijająca :(

Moglby ktos podac link?

[dopisane]
a moze by tak stworzyc nowy watek. Uzytkownik wpisywalby tekst, a w tym czasie probram sobie go porownuje

0

słownik mam już od jakiegoś czasu :)
Domyślałem się, że sprawdzanie będzie sporo czasu trwało :) No ale trudno. A może jest jakas inna możliwość zrobienia czegos takiego ??
Tak żeby szybko chodziło i ostatecznie sprawdzanie odbywało się po nacisnieciu przycisku sprawdz pisownie. Oczywiście wolałbym, żeby to się mogło odbywac podczas wprowadzania textu, ale jak sie nie da to trudno :)
NIech ktos podpowie, jak to zrobic, zeby działało szybko i nie zawieszało kompa ;P

0

szybciej wyszukac na pewno sie da, trzeba tylko znalezc dobry ku temu algorytm. Jesli w slowniku masz zapisane slowa wg. alfabetu i zalozmy kazde slowo jest w nowym wierszu to mozna podzielic slownik na 31 grup (chyba tyle jest liter w alfabecie polskim ;-) ) Program wiedzialby wtedy gdzie szukac np. chce sprawdzic czy istnieje słowo 'gitara' program Od razu wie ze trzeba zaczac (i skanczyc) szukac w grupie w ktorej slowa zaczynaja sie na litere 'g'... mozna dac kilka petli i sprawdzac po literce...

0

http://www.kurnik.pl/literaki/konkurs/

program "Lit", jest to program ze źródłem w delphi do gry w literaki. Po ułożeniu wyrazy sprawdza czy jestw słowniku, a robi to naprawdę szybko, lecze nie wiem jak, bo nie studiowałem źródła.

0

Pochwalony! Mam pomysł, nie należy on do najlepszych, ale jakoś trza to zrobić (wszystko jest możliwe) :P. Możesz na początku programu dać tabliczkę "ładowanie", podczas której do zmiennej jakiejś typu TStringList zostanie załadowany plik tekstowy (niestety nie należy to do dobrych rozwiązań, gdyż jest to w SPACJA końcu 30MB...). Podczas wciśnięcia przycisku ENTER lub SPACE (dla polskojęzycznych: WEJDŹ, lub PRZERWA :P ) można porozdzielać zdanie na słowa, a następnie sprawdzić poleceniem IndexOf (klasy TStringList, przy CaseSensive (dokładnie nie pamiętam, jakoś tak, teraz Delphi nie mam to nie powiem dokładnie :P) na True) czy takie słowo istnieje, jeżeli istnieje to odczepić się od tego i kolejne sprawdzać (oczywiście tylko z lini!! (przy większym obszarze to mogłoby dłużej trwać)). Jeżeli nie istnieje takie słowo w słowniku to podkreślić :P. Niestety, nie jestem pewny tego rozwiązania, gdyż nie mam Delphi, nie mam tego jak przetestować. To może się i tak zacinać przez polecenie IndexOf (może ono jakoś nieładnie sprawdzać TStringList), co doprowadzi do spowolnień. Jeżeli sposób nie zadziała, to sorki (chciałem mieć dobry uczynek na duszy P:P ).

0

Nie wiem czy to coś da bo nie próbowałem ale spróbuj tak. Zamiast szukać całego wyrazu najpierws poszukaj pierwszej litery tego wyrazu. Potem od miejsca gdzie znalazłeś tę pierwszą literę szukaj dwóch pierwszych liter szukanego wyrazu itd.

0

A mógłby ktos napisać taką przykładową procedurę, szukającą w pliku textowym wyraz wpisany w RE ?? I w jakim miejscu programu (noChange ?? RE)?? jestem dosyć początkujący i nie znam jeszcze wielu poleceń delphi :D [cya]

0

Wiesz, przykład to chyba każdy może dać. Na przykład tworzysz sobie TStringList, wgrywasz do niego słownik, a potem sprawdzasz :

if TStringList.ItemIndex('slowo') <> -1 then JestWSlowniku := true
  else JestWSlowniku := false;

Tylko jak u mnie jak próbowałem wgrać słownikk ten 30Mb to się komputer zawiesił po jakimś czasie, długim zresztą. Może ktoś ma pomysł, jak to szybko przerzucić do TStringLista zawartość pliku?

0

Załamujecie mnie:
http://4programmers.net/Forum/viewtopic.html?id=29951
Post Vogel'a

0

Dzięki. Ale tak przy okazji jeszcze jedna mała prośba. I proszę, nie śmiejcie się :) Ja naprawdę jetem początkujący i nie opanowałem jeszcze obsługi tablic :( Jeżeli ktoś mógłby mi napisać, jak powinna wyglądać ta tablica z wczytanymi z pliku wartościami, w którym miejscu kodu ją wstawić itp to bardzo proszę o pomoc!!!
Może załóżmy, że w pliku znajduje się kilka wyrazów i chcę je wczytać do tablicy slowa_w_slowniku. Następnie wywołać procedurę w poprzednim poscie (tą co szuka wyrazu w tablicy). Prosiłbym o napisanie przykładowego kodu tej tablicy i info, w której części programu mam ją umieścić (domyślam się, że w onCreate formy głównej, ale nie jestem pewny :()

0

Kurcze, Google nie znalazło zbyt wiele na temat Uniwersalnej Struktury Słownikowej. Jedną stronę angielskojęzyczną z gotowym źródłem, ale w C, a drugą polską, ale tylko z ogólnym zarysem tego problemu (jakieś źródła są w Pascalu, ale ja nie wiem, co tam w nich jest... http://www.orca2.mila.edu.pl/~astajniak/drzewa.htm). Gdyby ktoś mógł wyjaśnić ten problem w Artach lub skierować do jakiegoś URL, gdzie to jest jakoś lepiej wyjaśnione i gdzie są jakieś przykłady, to byłbym wdzięczny.

0

Co tu jest do rozumienia? Fragment (niedokończonego) notatnika wykorzystujący USS.

type
  PNode = ^TNode;
  TNode = record
    Last: Boolean; //Czy ostatnia litera słowa?
    Letters: array ['A'..'Z'] of PNode; //Poszczególne litery
  end;

type TDictionary = class
    FRoot: PNode;                               //Korzeń drzewa liter
    FStrings: TStrings;                         //Lista, na którą są wypisywane pasujące słowa
    FWord: string;                              //Aktualne słowo, do którego szukamy dopasowań
  private
    procedure Find(Word: string);              //Wyszukuje pasujące słowa
  public
    constructor Create;
    destructor Destroy; override;
    procedure Add(Word: string);                //Dodaje wyraz do słownika
    procedure Delete(Word: string);             //Usuwa wyraz ze słownika
    procedure Clear;                            //Czyści słownik
    property Word: string read FWord write Find;
    property List: TStrings read FStrings write FStrings default nil;
end;


var
  Form1: TForm1;
  Slownik: TDictionary = nil;

implementation

{$R *.dfm}

constructor TDictionary.Create;
(* Tworzy słownik i inicjuje zmienne *)
begin
  inherited Create;
  FStrings := nil;
  FWord := '';
end;

destructor TDictionary.Destroy;
(* Usuwa zawartość słownika i niszczy słownik *)
begin
  Clear;
  inherited Destroy;
end;

procedure TDictionary.Clear;
(* Czyści słownik *)

  procedure Empty(var Node: PNode);
  var
    i: Char;
  begin
    if Node = nil then
      Exit;
    for i := 'A' to 'Z' do
      Empty(Node^.Letters[i]);
    Dispose(Node);
    Node := nil;
  end;

begin
  Empty(FRoot);
end;

procedure TDictionary.Delete(Word: string);
(* Usuwa słowo *)

  function Remove(Node: PNode; Word: string; i: Integer): Boolean;
  var
    j: Char;
  begin
    if Node = nil then
    begin
      Result := True;
      Exit;
    end;
    if Remove(Node^.Letters[Word[i]], Word, i+1) then
    begin
      Dispose(Node^.Letters[Word[i]]);
      Node^.Letters[Word[i]] := nil;
    end;

    for j := 'A' to 'Z' do
      if Node^.Letters[j] <> nil then
      begin
        Result := False;
        Exit;
      end;
    if (not Node^.Last) or (i = Length(Word)+1) then
      Result := True
    else
      Result := False;
  end;

begin
  Remove(FRoot, UpperCase(Word), 1);
end;

procedure TDictionary.Add(Word: string);
(* Dopisuje słowo do słownika *)

  procedure Write(var Node: PNode; Word: string; i: Integer);
  begin
    if Node <> nil then
    begin
      if (i > Length(Word))or  not(Word[i] in ['A'..'Z']) then
        Node^.Last := True
      else
        Write(Node^.Letters[Word[i]], Word, i+1);
    end
    else
    begin
      New(Node);
      Node^.Last := False;
      FillChar(Node^.Letters, SizeOf(Node^.Letters), 0);
      Write(Node, Word, i);
    end;
  end;

begin
  if Word <> '' then
    Write(FRoot, UpperCase(Word), 1);
end;

procedure TDictionary.Find(Word: string);
(* Wyszukuje zgodne słowa *)

  function Match(Node: PNode; i: Integer): PNode;
  (* Wyszukuje pasujące fragmenty słowa *)
  begin
    if (i > Length(FWord)) or (Node = nil) then
    begin
      Result := Node;
      Exit;
    end;
    if FWord[i] in ['A'..'Z'] then
      Result := Match(Node^.Letters[FWord[i]], i+1)
    else
      Result := Node;
  end;

  procedure Print(Node: PNode; Word: string);
  (* Dopisuje do listy pasujące słowa *)
  var
    i: Char;
  begin
    if Node = nil then
      Exit;
    if Node^.Last then
      FStrings.Add(Word);
    for i := 'A' to 'Z' do
      Print(Node^.Letters[i], Word+i);
  end;

begin
  if not Assigned(FStrings) then
    Exit;
  FWord := UpperCase(Word);
  FStrings.Clear;
  Print(Match(FRoot, 1), FWord);
end;

Nie czepiać się, że mało komentarzy i niespójne nazewnictwo. Dopiero w trakcie powstawania to jest. Czuję, że jakiś prosty art będzie potrzebny...

0

Z tego co widzę, to to jest jakiś komponent, więc może zamiast arta walnąć go w kodach źródłowych i nie będzie problemu... Po pierwsze szybciej instaluje się gotowe komponenty niż pisze własne według jakichś wskazówek. A myślę, że niejednemu się to przyda jeszcze...

0

hmm.....
A ten słownik to jest w jakimś pliku czy gdzie ??
bo nie zauważyłem żeby było tam jakieś odwołanie do pliku ??
I może rzeczywiście skoro to jest komponent, to umieścić go w źródłach i zrobić jakiś krótki opis korzystania z niego ??

0

Nie wiem... u mnie to nie chce działać, wywala się na

Node <> nil

w procedurze write... Acces Violation i tak dalej.

0
  1. Nie komponent tylko obiekt.
  2. Jak już wspomniałem, dopiero piszę to, dlateg m. in. nie ma jeszcze zapisu na dysk i odczytu z dysku bazy danych.
  3. Jak z pkt. 2 wynika, jeszcze zdarzają się błędy. Nie wiem co jest nie tak w procedurze Write. U mnie działało ostatnio, ale możliwe, że coś zmieniałem i zapomniałem.

Umieszczę do w kodach źródłowych, jak tylko skończę i wyszlifuję. Na razie nie mam czasu brać się za to... Ale może jeszcze w ciągu tygodnia zdążę się za to wziąć.

0

Z tego co zobaczyłem to ten program szuka normalnie w wątku ? [spoko]

1 użytkowników online, w tym zalogowanych: 0, gości: 1