Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.11.25;
Скачать: [xml.tar.bz2];

Вниз

Pos с конца строки   Найти похожие ветки 

 
Vlad0   (2007-11-01 18:49) [0]

Существует ли в Delphi функция Pos, которая ищет вхождения с конца строки? Если нет, то возможно у вас есть хорошо оптимизированный вариант?


 
Palladin ©   (2007-11-01 18:52) [1]

Function RPos(Const s:String;c:Char):Integer;
Var
 i:Integer;
Begin
 For i:=Length(s) Downto 1 Do
  If s[i]=c Then
   Begin
    Result:=i;  
    Exit;
   End;
 Result:=0;
End;


 
Vlad0   (2007-11-01 18:54) [2]

Хмм.. а если у меня для поиска строка целая нужна, а не Char...


 
Плохиш ©   (2007-11-01 18:59) [3]

PosEx + голова


 
palva ©   (2007-11-01 20:01) [4]

Я себе вот такую написал. Мне нужна была функция максимально похожая на соответствующую функцию бейсика. Можете переделать под себя или пользоваться этой.

{$APPTYPE CONSOLE}
uses SysUtils, StrUtils;

const
 vbBinaryCompare = 0;
 vbTextCompare = 1;

{
The InStrRev function returns the position of the first occurrence
of one string within another. The search begins from the end of string,
but the position returned counts from the beginning of the string.

The InStrRev function can return the following values:
}

function InStrRev(const Str, Pat: String; Strt: Integer = -1;
          Scmp: Integer = vbBinaryCompare): Integer;

{
Parameter Description
Str - The string to be searched
Pat - The string expression to search for
Strt Optional. - Specifies the starting position for each search.
The search begins at the last character position by default (-1)
Scmp Optional. - Specifies the string comparison to use. Default is 0
Can have one of the following values:
0 = vbBinaryCompare - Perform a binary comparison
1 = vbTextCompare - Perform a textual comparison

If Str is "" - InStrRev returns 0
If Pat is "" - InStrRev returns start
If Pat is not found - InStrRev returns 0
If Pat is found within Str - InStrRev returns the position at which match
is found
If Strt > Length(Str) - InStrRev returns 0
}

var
 Len, LenP: Integer;
 P: PChar;
 so: TStringSearchOptions;
begin
 Len := Length(Str);
 LenP := Length(Pat);
 if Strt = -1 then Strt := Len;
 if (Len = 0) Or (Strt > Len) Or (LenP > Len) then
   Result := 0
 else if LenP = 0 then
   Result := Strt
 else begin
   if Strt <=0 then raise Exception.Create("Wrong InStrRev parameter");
   so := [];
   if Scmp = vbBinaryCompare then
     so := [soMatchCase];
   P := SearchBuf(PChar(Str), Len, Strt, 0, Pat, so);
   if P = Nil then
     Result := 0
   else
     Result := P - @Str[1] + 1;
 end;
end;

begin
 WriteLn(InStrRev("qWeQwEqWe", "we", 7, vbTextCompare)); // 5
end.


 
Marser ©   (2007-11-01 20:31) [5]

Обратить обе строки и заюзать обычный pos - проще некуда :-)


 
Dib@zol ©   (2007-11-01 21:49) [6]

Собсна вот. Кодил прямо щас, на ходу, поэтому наверняка где-нибудь можно оптимизировать. Читает строчку str с конца, а результат возвращает "с начала" этой строчки. Если нужно отсчитывать "с конца" - раскомментируйте 3 строчки блока @done.

function PosR(sub, str:string):Cardinal;
asm
 PUSH EAX;
 PUSH EBX;
 PUSH EDX;
 PUSH EDI;
 PUSH ESI;

 MOV ESI, str;
 MOV EDI, sub;
 MOV Result, 0;
 XOR EAX, EAX;
 MOV EBX, 1;

 MOV EAX, DWORD PTR [ESI-4];
 MOV EBX, DWORD PTR [EDI-4];

 @rept:
 CMP EAX, 0;
 JE @null;
 MOV DL, BYTE PTR [ESI+EAX-1];
 CMP DL, BYTE PTR [EDI+EBX-1];
 JNE @next;

 MOV Result, EAX;

 CMP EBX, 1;
 JE @done;
 DEC EBX;
 JMP @norm;

 @next:
 CMP Result, 0;
 JNE @null;
 @norm:
 DEC EAX;
 JMP @rept;

 @done:
 //MOV EBX, DWORD PTR [ESI-4];
 //SUB EBX, EAX;
 //ADD EBX, 1;
 MOV Result, EBX;
 JMP @exit;

 @null:
 MOV Result, 0;

 @exit:
 POP ESI;
 POP EDI;
 POP EDX;
 POP EBX;
 POP EAX;
end;


 
Dib@zol ©   (2007-11-01 21:59) [7]

Тфу. Звиняюсь, не работает :(


 
Dib@zol ©   (2007-11-01 22:18) [8]

function PosR(sub, str:string):Cardinal;
asm
 PUSH EAX;
 PUSH EBX;
 PUSH EDX;
 PUSH EDI;
 PUSH ESI;

 MOV ESI, str;
 MOV EDI, sub;

 MOV EAX, DWORD PTR [ESI-4];

 @eval:
 MOV Result, 0;
 MOV EBX, DWORD PTR [EDI-4];

 @rept:
 CMP EAX, 0;
 JE @null;
 MOV DL, BYTE PTR [ESI+EAX-1];
 CMP DL, BYTE PTR [EDI+EBX-1];
 JNE @next;

 MOV Result, EAX;

 CMP EBX, 1;
 JE @done;
 DEC EBX;
 JMP @norm;

 @next:
 CMP Result, 0;
 JNE @eval;
 
 @norm:
 DEC EAX;
 JMP @rept;

 @done:
 //MOV EBX, DWORD PTR [ESI-4];
 //SUB EBX, EAX;
 //MOV EAX, EBX;
 //ADD EAX, 1;
 MOV Result, EAX;
 JMP @exit;

 @null:
 MOV Result, 0;

 @exit:
 POP ESI;
 POP EDI;
 POP EDX;
 POP EBX;
 POP EAX;
end;

Вот. Тесты не выявили существенных отличий от быстродействия стандартного Pos :)



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2007.11.25;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.055 c
2-1193782252
vr-online
2007-10-31 01:10
2007.11.25
Жрет память


2-1193682578
mahab
2007-10-29 21:29
2007.11.25
Коррректная обработка загрузки испорченных изображений


1-1189278923
Efir
2007-09-08 23:15
2007.11.25
Открытие файлов


15-1193056466
Антон Шестаков
2007-10-22 16:34
2007.11.25
Создание справки


2-1193741998
Quart
2007-10-30 13:59
2007.11.25
Ячейка DBGrid





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский