Показать сообщение отдельно
  #10  
Старый 29.11.2013, 13:28
Аватар для seeman_tm
seeman_tm seeman_tm вне форума
Новичок
 
Регистрация: 03.02.2011
Сообщения: 79
Репутация: -2306
По умолчанию

Не стану создавать очередную тему. Зачем хламить форум.

Написал функцию. Цель её проста.
Поиск подстрок в строке. Но основано на массивах байтов.
Что, судя по выше выложенным диаграммам, даст наибольшую скорость поиска.
О её плюсах.
Скорость проведения поиска (Надо проверить на тестах и сравнить результаты с аналогичными функциями поиска уже подстроки в строке).
Есть возможность задать функции несколько подмассивов сразу. (Функция возвращает позицию первого найденного подмассива и найденный подмассив)
Поиск можно проводить с любой позиции.
В случае, если надо провести поиск с учётом регистра символов, то имеется и эта возможность.

Собственно сама функция.
Код:
Type ArrayOfByte = Array Of Byte;

// MainSub - Массив искомых подмассивов
// Main - Массив в котором производится поиск подмассивов
// Finded - В случае успеха содержит найденный подмассив, в противном сдучае пуст
// Offset - Позиция с которой производить поиск подмассивов
// IgnoreCase - Игнорирование регистра
// Result - В случае успеха возвращает позицию с которой начинается подмассив в массиве
// (Массив и подмассивы начинаются с индекса 0
// В иных случаях в Result возвращается -1
Function TForm4.PosEx(Const MainSub: Array Of ArrayOfByte; Const Main: ArrayOfByte; Var Finded: ArrayOfByte; Const Offset: Cardinal = 0; Const IgnoreCase: Boolean = False): Integer;
var
  s: String;
  Index, IndexM, IndexS: Integer;
  Sub: Array Of ArrayOfByte; // Массив подмассивов, которые помещаются в Массив с учётом отсупа Offset
begin
  // Если отступ (Offset) превышает границы массива то выходим.
  if Offset > High(Main) then
    Begin
      SetLenGth(Finded, 0);
      Result := -1;
      Exit;
    End;

  // Перебираем подмассивы. Берём только те подмассивы, которые помещаются в Массив с учётом отсупа
  // и длинна больше 0
  for Index := Low(MainSub) to High(MainSub) do
    Begin
      // Если длинна массива больше 0
      // и подмассив помещается, то добавляем его в Sub
      if (LenGth(MainSub[Index]) > 0) and (LenGth(MainSub[Index]) <= ((LenGth(Main) - Offset) + 1)) then
           Begin
             SetLenGth(Sub, LenGth(Sub)+1);
             SetLenGth(Sub[High(Sub)], LenGth(MainSub[Index]));
             Move(MainSub[Index,Low(MainSub[Index])], Sub[High(Sub),Low(Sub[High(Sub)])], LenGth(Sub[High(Sub)]));
           End;
    End;

  // Если у нас нет ни одного подмассива прошедшего проверку
  if LenGth(Sub) = 0 then
    Begin
      SetLenGth(Finded, 0);
      Result := -1;
      Exit;
    End;

  for IndexM := OffSet to High(Main) do
    Begin
      for IndexS := Low(Sub) to High(Sub) do
         Begin
{           // Если подмассив больше не помещается в массив с учётом сдвига к концу массива, то убираем его из возможных
           While LenGth(Sub[IndexS]) > ((LenGth(Main) - Offset) + 1) Do
               Begin
                  Move(Sub[IndexS+1], Sub[IndexS], LenGth(Sub[IndexS])-IndexS);
                  SetLenGth(Sub, LenGth(Sub)-1);
                  Continue;
               End;  }
           for Index := Low(Sub[IndexS]) to High(Sub[IndexS]) do
             Begin
               if (Sub[IndexS,Index] <> Main[IndexM+Index]) Then
                  Begin
                     If Not(IgnoreCase) then
                        Break
                      Else
                        Begin
                          If ((Sub[IndexS,Index] >= 65) and (Sub[IndexS,Index] <= 90))
                                then
                                  Begin
                                    if (Sub[IndexS,Index] + 32 <> Main[IndexM+Index]) Then Break;
                                    Continue;
                                  End;
                          If ((Sub[IndexS,Index] >= 97) and (Sub[IndexS,Index] <= 122))
                                then
                                  Begin
                                    if (Sub[IndexS,Index] - 32 <> Main[IndexM+Index]) Then Break;
                                    Continue;
                                  End;
                        End;
                  End;
             End;
           if Index > High(Sub[IndexS]) then
            Begin
              Result := IndexM;
              Finded := Sub[IndexS];
              Exit;
            End;
         End;
    End;
  SetLenGth(Finded, 0);
  Result := -1;
End;
Ответить с цитированием