Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ Прямой поиск строки

Автор: Lo 17.11.2003 18:49

Рассказываю: необходим код по прямому поиску строки в тексте. Прямой, значит символьные элементы заносятся в массив и подстрока последовательно смещаясь сравнивается со строкой. Такой алгоритм есть еще у Вирта, но достаточно древний. А необходимо реализовать поиск со знаками *, ?. Только нужен элегантный код. Заранее спасибо

Автор: ___ALex___ 17.11.2003 22:39

см. исходник Pos-а

Автор: Lo 18.11.2003 17:30

Что значит Pos-a  в исходниках?

Автор: mvg 18.11.2003 18:07

поконкретней о задаче

Автор: GLuk 18.11.2003 22:53

Покажи что сам написал, юзая "древний" способ Вирта.
После знака * могут следовать какие-нибудь символы (вероятнее всего могут конечно, но вдруг чо)??
Исходник Pos'a - это либо дизассемблить тот участок кода (Pos - это процедурка такая в паскале) или просто поглядеть в дебуггере

Автор: Lo 19.11.2003 17:08

mvg
Задача: найти слово в тексте. Проще - подстроку в строке. Но стандатные функции работы со строками не используются(Pos). У вирта есть алгоритм поиска, когда текст представлен, как массив char'ов и слово ищется в нем, сравнивая почленно элементы массива и сдвигая дальше. Вопрос: как эффективно реализовать поиск, если знаки * и ? встречаются в искомом слове. (Так, возможно, ищутся по имени файлы в винде)

Автор: Lo 19.11.2003 17:12

Gluk
Исходники Pos-а не пойдут: там не реализован поиск с *.

Автор: trminator 19.11.2003 23:33

на pascal.sources.ru много таких исходников

Автор: Lo 24.11.2003 16:09

Спасибо всем! Тему можно закрывать. Все получилось

Автор: trminator 24.11.2003 21:14

Так выложи, что получилось-то. Другим тоже интересно!

Автор: Lo 27.11.2003 18:52

Мне текст отправить в исходники или кусок кода выложить сюда?

Автор: GLuk 27.11.2003 19:31

Для полного завершения темы по ходу лучше сюда постить, а после в исходники.

Автор: GLuk 29.11.2003 12:38

Цитата
Мне текст отправить в исходники или кусок кода выложить сюда?


кусок кода выложить сюда?

Автор: Lo 1.12.2003 17:54

Соответственно, в главной вызывается SmpStr

Код
procedure MaskForm(var M: string);
begin
 i:=1;
 if first=1 then
 begin
   inc(first);
   While True Do
   Begin
     J:=Length(M);
     While I<Length(M) Do
     Begin
       If (M[I]='?') And (M[I+1]='*') Then Delete(M,I,1);
       If (M[I]='*') And (M[I+1]='?') And (I<Length(M)) Then Delete(M,I+1,1);
       If (M[I]='*') And (M[I+1]='*') And (I<Length(M)) Then Delete(M,I,1);
       Inc(I);
     End;
     If J=Length(M) Then Break;
     I:=1;
   End;
 end;
end;

Function StrCmp(S,Mask:String):boolean;
Var
 Msk,St: string;
Begin
 { Приведение маски к формальному виду. Производится однократно }
 MaskForm(Mask);
 { Блок сравнения с маской }
 Ok:=True;
 I:=1;
 J:=0;
 repeat
   j:=j+1;
   i:=1;
   While TRUE Do
   Begin
    Case Mask[I] Of
    '*':
     Begin
      if I=Length(Mask) then Ok:= true
      else
      begin
        washere:= true; { Рекурсивная проверка совпадений для части строки, идущей после символа '*' }
        Msk:=Copy(Mask,I+1,Length(Mask)-I+1);
        St:=Copy(S,J,Length(S)-J+1);
        While (St<>'') And (NOT StrCmp(St,Msk)) Do
        Delete(St,1,1);
        If St='' Then Ok:=False
                 else
                 begin
                   J:=Pos(St,S);
                   break;
                 end;
      end;
     End;
   '?':
    Begin
     if I=Length(Mask) then OK:= true
     else
     begin
       If (I=Length(Mask)) And (J<Length(S)) Then Ok:=False;
       If J>Length(S) Then Ok:=False;
       Inc(J);
     end;
    End;
   Else If Mask[I]<>S[J]
   Then begin
          Ok:= false;
          break;
        end
   Else begin
          if FirstIn= 0 then FirstIn:= J;
          Inc(J);
          Ok:= true;
        end;
   End;
   q:= Length(S);
   If J-1>Length(S) Then Ok:=False;
   If Not Ok Then Break;
   w:= Length(Mask);
   Inc(I);
   If I>Length(Mask) Then Break;
 End;
 w:= Length(Mask);
 q:= Length(S);
 if washere then begin
                   if (j=w+1) or (j=w) then Yes:= true
                 end
 else
 begin
   if (i>w) then Yes:= true
 end
 until (j>=q) or Yes;
 StrCmp:=Ok;
end;