J2ME - przeszukiwanie dużego pliku

0

Witam,
Na wstępie zaznaczę, że jestem dotnetowcem, ale muszę sobie napisać aplikację na komórkę, konkretniej słownik. W tym celu, w swoim JARze umieściłem plik txt z 75000 linii. A ponizej zamieszczam kod, który służy mi do jego przeszukiwania po wciśnięciu przycisku szukaj:

                  stringItem1.setText("\n");
        try{
         in = new InputStreamReader(this.getClass().getResourceAsStream("words.txt"), "UTF-8");
        }
        catch(UnsupportedEncodingException e)
        {}
        catch(IOException e){}
                StringBuffer sb = new StringBuffer();
      int chr = 0;   
      try{
      while ((chr = in.read()) != -1)
      {
          sb.append((char) chr);
          if((char)chr=='\n')
          {
              if(sb.toString().toLowerCase().indexOf(textField.getString().toLowerCase())!=-1)
                  stringItem1.setText(stringItem1.getText()+sb.toString());
              sb.delete(0, sb.length());
              
          }
      }

      }
      catch(IOException e){}

Moje pytanie brzmi. Czy da się przeszukiwać szybciej? Bo otrzymanie wyników trwa.. klika minut :(

0

Hmmm...
Wolne jest bo wykorzystujesz najwolniejsza metode przeszukiwania w ktorej wyszukanie jednego slowa moze "trwac" od 1 do 75000 odczytow. Ja proponowalbym tak:

  • posortowac tekst w bazie;
  • zrobic drugi plik zawierajacy offsety kolejnych linii pliku z tekstem (tzn z informacja gdzie w pliku zaczyna sie ktora linia) aby moc potem zlokalizowac i wszytac konkretna linie tekstu. Bedzie na tyle maly, ze bedzie mozna go nawet wczytac do pamieci (4 * 75000 bajtow) ale nie jest to konieczne;
  • zastosowac np metode bisekcji czyli (zakladamy, ze masz N linii): sprawdzasz linie 1, linie N i linie N/2 (czyli posrodku przedzialu). Jesli 1, N/2 lub N jest trafiona to koniec. Jesli nie to sprawdzasz czy tekst, ktory szukasz jest wiekszy czy mniejszy od linii N/2 (funkcja compare zwraca -1, 0 lub 1 w zaleznosci czy tekst jest mniejszy, wiekszy czy taki sam). Jesli wieksze to powtarzasz wyszukiwanie w przedziale N/2 do N, a jesli mniejsze to 1 do N/2. I tak w kolko, az trafisz :]

Troche namieszalem pewnie (jest 7 rano :] ) ale ogolnie mysle, ze da sie z tego cos napisac. Zwlaszcza, ze bedzie to zdecydowanie szybsze niz Twoje rozwiazanie...

0

Tak, wiem o algorytmach, które opisałeś, jednak mi zależy, żeby wypisać każde słowo zawierające podciąg szukany. Czyli np. jeśli wpisałeś sfera, to żeby znalazło stratosferę, atmosferę itp itd.

0

No to nie wiem czy da sie to przyspieszyc...
Moze jakis bufor zrob do ktorego bedziesz wczytywal fragmenty pliku i parsowal caly blok tekstu zamiast pojedyncze linie? Innych pomyslow juz nie mam :/

0

to prawdopodobnie nie będzie najprostszy algorytm, ale może być całkiem wydajny
gdy na uczelni kazali nam napisać program który operuje na słowniku zalecane było użycie struktury TRIE
generalnie idea jest taka że masz sobie drzewo, na początku wiadomo... korzeń, do korzenia doczepiasz literki tak aby kolejne "piętra" tworzyły słowo, wikipedia tudzież google Ci to prawdopodobnie lepiej wyjaśni
Do tego indeksujesz wystąpienia wszystkich liter w drzewie, i jak szukasz np. wyrazu sfera, to wybierasz z indeksu wszystkie wystąpienia "s" i sprawdzasz czy występuje jego dziecko "f" jeśli tak to sprawdzasz czy występuje dziecko "e" węzła "f" itd.

w każdym razie jeśli Ci ten sposób odpowiada musisz przygotować się na wiele linii kodu, przemyślenie struktur danych, ale powinno działać znacznie szybciej, nie wiem jakie to będzie miało wymagania odnośnie pamięci

a do tego nie wiem czy jest w J2ME, ale przydałby się jakiś buforowany strumień, bo teraz prawdopodobnie czyta znak po znaku z pamięci telefonu co raczej mu nie służy

to by było na tyle ode mnie

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