Wyszukiwanie... mega wyszukiwanie...

0

mam 40mb plik ktory jest zbiorem wyrazow - potrzebne mi jest to jako slownik... i terach chodzi o wyszukiwanie (a w zasadzie sprawdzanie czy konkretny wyraz tam istnieje)... naturalnie wiem jak sprawdzic czy wyraz istnieje w danym ciagu ale jak sprawic zeby w tym 40mb pliku zrobic to tak aby nie obciazyc za bardzo pamieci i procesora - bo samo zaladowanie do zmiennej moze spowodowac zawieszke kompa (jak laduje to do WordPada to mi komp prawie wisi - a WordPad zajmuje ponad 70mb pamieci). chodzi o to zeby najlepiej nie wzytywac pliku do pamieci tylko operowac na zasadniczym pliku... ale jak to zrobic? szubko, sprawnie, bez obciazen... PROSZE!

0

filestream / textfile + f1

0

Zastanow sie czy nie uzyc drzew w celu zmniejszenia zajetosci pamieci i zwiekszenia szybkosci wyszukiwania.

0

uzylem readln ale to trwa w niekonczonosc... tam jest 2.5 mln linii wiec troche to w zasadzie trwa... jak to zrobic jeszcze inaczej? moze jakis przykladowy kod?

0

Nie wiem, czy to pomoże, ale...
Jeśli masz plik z wyrazami, to może go posortuj(o ile nie jest jeszcze posortowany). Zapamiętaj od kórej linijki zaczynają się wyrazy na 'a' na 'b' itd. Jeśli bedziesz sprawadzał czy dany wyraz istnieje w pliku to zaczniesz wyszukiwanie od odpowiedniej linijki.

0

Posortować? .. Ty wiesz ile to zajmie? :-/

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
  TSearch = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;

var
  Form1: TForm1;

implementation

procedure TSearch.Execute;
var
  T: TextFile;
  s: string;
  i: Integer;
begin
  AssignFile(T, 'C:\test.txt');
  Reset(T);
  i := 0;
  repeat
    Readln(T, s);
    if pos('szukana fraza', s) > 0 then
      Form1.Memo1.Lines.Add('Linia: "' + s + '" nr : ' + IntToStr(i));
    Inc(i);
  until EOF(T);
  CloseFile(T);
  Form1.Label1.Caption := 'Koniec szukania';

end;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  Search: TSearch;
begin
  label1.Caption := 'Szukanie...';
  Search := TSearch.Create(False);

end;

end.
0

Ile to zajmie to nie wiem, ale przecież nie trzeba dokładnie sortować wyrazów wg alfabetu. Wydaje mi się, ze znacznie przyspieszy się wyszukiwanie gdy wyrazy będą chociaż posortowane wg pierwszych literek. Zresztą posortowac plik wystarczy raz.

0

Ile to zajmie to nie wiem, ale przecież nie trzeba dokładnie sortować wyrazów wg alfabetu. Wydaje mi się, ze znacznie przyspieszy się wyszukiwanie gdy wyrazy będą chociaż posortowane wg pierwszych literek. Zresztą posortowac plik wystarczy raz.

wg mnie też należałoby posortować plik albo wg pierwszych liter (czyli przeszukujesz wtedy tylko około 1/20 pliku), albo wg kategorii wyrazów

Detox: posortować przecież można w wątku, albo kilku (wystarczy podzielić plik na części)

// przecież tak właśnie napisalem wyszukiwanie :) - detox

0

Wiec moze rozwiaze problem: wyrazy sa juz posortowane. Ale teraz pytanie brzmi nastepujaco: przykladowo slownik sie zmienia, wyrazy sa dodawane wiec nastepuje przesuniecie... Wtedy maly zonk... Bo sposob Detoxa jest na pewno lepszy niz moj ale mimo wszystko przeszukanie slownika trwa okolo minuty... Na takie cos nie bardzo moge sobie pozwolic :/ Pomyslalem ze mozna by zrobic inaczej... Sprawdzic najpierw srodkowa czesc slownika - jezeli wyraz jest w pierszej polowie (wystarczy sprawdzic czy wedlug alfabetu jest wczesniej czy pozniej), potem to jeszcze raz na polowe... Tak dajmu na to 10 razy - wtedy pozostaje do sprawdzenia ok 30 wyrazow... Wtedy juz banal... Ale jak moge sprwdzic 'dynaczmicznie' ile jest linii? Musze leciec najpierw petla z EOF (co trwa i trwa...) czy mozna to jakos szybciej odczytac ilosc linii?

0

Poszukaj artykułów o uniwersalnej strukturze słownikowej, tam będzie odpowiedź na twoje pytania.

0

:/ Jakas wieksza podpowiedz? W kazdym razie da sie sprawdzic ilosc linii czy nie bardzo? Jak to zrobic zeby wszystko bylo w miare sprawnie...?

0

Ja osobiście nie znam żadnej faunkcji, która podawałaby ilość linii w pliku. Pewnie trzeba to zrobić programowo. Jednak jeśli tylko Twój program korzysta z pliku z danymi, to może warto policzyć linijki raz a liczbe linijek zapisać np do pliki *.ini. Gdy będziesz np. dopisywał wyrazy do pliku jednocześnie zmienisz dane w pliku *.ini. Jeśli natomiast plik z danymi jest obsługiwany przez inne programy, wówczas może policz linijki zaraz po uruchomieniu programu i zapamiętaj je w zmiennej.

0

To co teraz napisales z cykilcznym polowkowaniem zakresu najlepiej wykonac rekurencyjnie. Podobna metode wykorzystuje sie w algorytmie QuicSort.

Co to wczensiejszego problemu to proponowalbym podzielenie pliku z wyrazami na kilka plikow z ktorych kazdy zawieralby wyrazy zaczynajace sie na okreslona litere np: a.txt, b.txt, c.txt... wtedy tyllko pobierasz piersza litere szukanego wyrazu i przeszukujesz okreslony plik.

Czesto sam jestem zmuszony operowac na duzych plikach textowych, nawet duzo wiekszych niz 40mb i mysle ze jest to jeden z lepszych pomyslow na rozwiazanie tego typu problemu.

Pozdrawiam

0

Wrzuc to do dowolnej bazy danych i potraktuj indeksem - rozwiaze to rowniez problem dodawania i usuwania wyrazow.

0

Napisałem kiedyś taki program, wyszukiwał w słowniku (słownik zajmował zdaje się 38MB) podane słowo, poza tym wyposażyłem go w opcje przydatne przy rozwiązywaniu krzyżówek, czy graniu w scrable. Jeśli chodzi o rozwiązywanie krzyżówek to podajesz litery jakie masz dane w haśle np. po__cy a program powie ci że to słowo to pomocy (nie wiem może jeszcze jakieś). W scrablach natomiast podajesz jakie masz litery np. "dvdfabvdfbd" a program ułoży ci wszystkie możliwe wyrazy składające się wyłącznie z danych liter (wyszuka je w słowniku) Wyszukiwanie trwa 2-3 sekundy, przy czym program nie zawiesza się na ten czas tylko po prostu dodaje znalezione słowa do ListBox-a i w każdej chwili możesz przerwać dalsze wyszukiwanie (oczywiście jeśli zdążysz). Jak chcesz to mogę ci go przesłać na maila.

0

Oczywiście wraz z źródłami :)

0

to bardzo bym prosil! serio! jak mozesz wyslij na [email protected] Jezeli zadziala to masz u mnie bro :) THX!

0

moim zdaniem... posortuj ten plik (dlugo to zajmie, ale jednorazowo) a nastepnie posortowane wyrazy pozapisuj do roznych plikow odpowiadajacym literom alfabetu...mozna by sie pokusic o ograniczenie na plik danej litery do powiedzmy 1000 slow i numerowac pliki (e.g. a_001.txt, a_002.txt itd)

0

osz ja cie... nie spojrzalem na date :D.. ale ciekawe w jaki sposob autor rozwiazal ten problem ??

0

Jak już wątek jest odświeżony, to pozwolę sobie się dopisać. Jest na 4p artykuł albo wskazówka jak wyszukiwać binarnie w pliku tekstowym. To powinno być dokładnie to, czego potrzeba do rozwiązania tego problemu.

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