Wyszukiwanie wzorca w tekście

0

Witam
Mam napisac na zajęcia program do szukania wzorca. Napisałem i powstal problem: przy większych długościach tekstu w ansistring wywala mi błąd(screen w załączniku)
Bardzo prosze o szybką pomoc :)

Oto kod:

program szukanie_good;

uses Math;

const
  zp = 20;  // kod pierwszego znaku alfabetu
  zk = 126;  // kod ostatniego znaku alfabetu

procedure tab(p:ansistring;var Last:array of integer);  //procedura tworząca tablice Last, która przechowuje ostatnie pozycje poszczególnych znaków we wzorcu
var i:integer;
  begin
      for i := 0 to zk - zp do Last[i] := 0;
      for i := 1 to length(p) do Last[ord(p[i]) - zp] := i;
  end;

procedure szukaj(s,p:ansistring;var Last:array of integer;var wyniki:text); //procedura przeszukująca tekst w poszukiwaniu wzorca oraz zapisujaca pozycje wzorca w pliku: wyniki_szukania.txt
var i,j:integer;
begin
i := 1;
 while i <= length(s) - length(p) + 1 do
 begin
   j := length(p);
   if (j=0) then
     begin
      append(wyniki);
      writeln(wyniki,'Nie wprowadzono wzorca tekstu');
      close(wyniki);
      writeln('Nie wprowadzono wzorca tekstu');
      break;
     end;
   while (j > 0) and (p[j] = s[i + j - 1]) do dec(j);
   if j = 0 then
   begin
     append(wyniki);                                                 //zapis pozycji wzorca w pliku tekstowym 'wyniki_szukania.txt'
     writeln(wyniki,'Znaleziono wzorzec w tekscie, pozycja: ', i );
     close(wyniki);
     writeln('Znaleziono wzorzec w tekscie, pozycja: ', i );
     inc(i);
   end
   else inc(i,max(1,j - Last[ord(s[i+j-1]) - zp]));
 end;

end;

var
  s,p : ansistring;   //s-string, p-wzorzec(pattern)
  Last : array[0..zk-zp] of integer; //tablica ostatnich pozycji poszczegolnych znaków we wzorcu p
  wyniki:text;  //zmienna do obslugi pliku tekstowego
begin
  assign(wyniki, 'wyniki_szukania.txt');  //powiazanie zmiennej wyniki z plikiem tekstowym 'wyniki_szukania.txt', oraz przygotowanie jej do zapisu
  rewrite(wyniki);
  close(wyniki);

  // Prosimy użytkownika o podanie tekstu, oraz wzorca
  writeln('Podaj tekst: ');
  readln(s);

  writeln('Podaj wzorzec');
  readln(p);

  // dla wzorca obliczamy tablicę Last[]
  tab(p,Last);


  // szukamy pozycji wzorca w łańcuchu
  szukaj(s,p,Last,wyniki);

  writeln;
  readln();
end.
0

Ten kod jest jakiś dziwny... Nie rozumiem po co to całe przekazywanie zmiennej plikowej do procedury i mieszanie funkcjonalności; Procedura Szukaj (jak sama nazwa wskazuje) ma wyszukiwać wzorzec w tekście, a ponadto zajmuje się sprawdzaniem i wpisywaniem różnych tektów do pliku; Przemieszałeś wszystko niepotrzebnie i teraz masz problem ze zrozumieniem kodu i wyłapaniem błędów;

Masz mnóstwo nic nie mówiących jednoznakowych zmiennych i parametrów, a cały kod jest słabo sformatowany, przez co jest wystarczająco nieczytelny, bo nie rozumieć co robi i do czego służy; Ma kilkadziesiąt linii, a i tak nie możesz znaleźć błędu...


Napisz więc funkcję, która przeszuka tekst i zwróci ilość znalezionych wzorców; Procedura Szukaj ma tylko przeszukiwać tekst i zwracać wynik, a na zewnątrz (w bloku, który z niej korzysta) odpowiednie dane będą zapisywane w pliku; Funkcja w argumentach powinna przyjmować tekst do przeszukania i wzorzec do odnalezienia, a zwracać tablicę z indeksami znalezień - nic więcej;

const
  zp = 20;  // kod pierwszego znaku alfabetu
  zk = 126;  // kod ostatniego znaku alfabetu

Co to jest? Jeśli piszesz o kodzie ASCII to jesteś w niewyobrażalnie wielkim błędzie;

Podsumowując - napisz ten kod od nowa bez kombinacji z parametrami i mieszania funkcjonalności; Poniżej przykładowa konstrukcja (bez właściwego wyszukiwania, żeby nie zabierać Ci całej przyjemności kodzenia):

type
  TIndexesSet = set of Byte;

  function Search(AText, APattern: AnsiString; out AIndexes: TIndexes): Integer;
  begin
    // wyszukiwanie wzorca w tekście

    // jeśli wzorzec zostanie znaleziony, wystarczy dodać jego pozycję
    // do zbioru, np. procedurą 'Include' lub zwykłym operatorem
  end;

var
  fOutput: TextFile;
  strText, strPattern: AnsiString;
  isIndexes: TIndexesSet;
  intCount: Integer;
begin
  Write('Podaj tekst: ');
  ReadLn(strText);

  if strText = '' then
    Write('Wprowadzono niepoprawny tekst.')
  else
  begin
    Write('Podaj wzorzec: ');
    ReadLn(strPattern);

    if strPattern = '' then
      Write('Wprowadzono niepoprawny wzorzec.')
    else
    begin
      AssignFile(fOutput, 'wyniki_szukania.txt');
      ReWrite(fOutput);
      try
        intCount := Search(strText, strPattern, isIndexes);

        if intCount = 0 then
          // wpisanie informacji o nie znalezieniu wzorca
        else
          // wpisanie informacji o znalezionych wzorcach
          // indeksy pozycji są w zbiorze 'isIndexes'
      finally
        CloseFile(fOutput);
      end;
    end;
  end;
  ReadLn;
end.

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