0
点赞
收藏
分享

微信扫一扫

【Pascal/Delphi】实现类似于glibc中的strrstr函数(反向查找字符串)

皮皮球场 2022-04-02 阅读 46
开发语言

1.初步实现

//在字符串haystack中查找字符串needle最后一次出现的位置,
//找到返回needle在haystack中的索引值,否则返回0
//(注:Pascal/Delphi中string类型的索引从1开始).
function strrstr(const haystack, needle: string): Integer;
var 
i, j, nLen: Integer;
begin
  strrstr:= 0;
  i:= Length(haystack);
  nLen:= Length(needle);
  j:= nLen;
  if(i = 0) or (j = 0) or (j > i)then
    Exit;

  repeat
    if haystack[i] = needle[j] then
    begin
       if j = 1 then
       begin
         strrstr:= i;
         Exit;
       end;
       Dec(j);
    end
    else j:= nLen;
    Dec(i);
  until i = 0
end;

2.调用测试

var str: string;
begin
       //0      //1       //2
       //1234567890123456789012345
  str:= 'Touch fish make me happy!';
  Writeln(strrstr(str, 'happy'));
  Writeln(strrstr(str, 'me'));
  Writeln(strrstr(str, 'm'));
  Writeln(strrstr(str, 'fish'));
  Writeln('---------------------------------------');
  Writeln(strrstr(str, 'Study make me happy!'));
  Writeln(strrstr(str, 'happy?'));
  Writeln(strrstr(str, 'mee'));
  Writeln(strrstr(str, 'touch'));
  Readln;
end.

3.运行结果

😃
在这里插入图片描述

3.改进函数

函数逻辑和运行结果都是正确的,哪里可以改进呢?

函数中使用循环查找出haystack尾部与needle尾字符相等的字符后,索引needle中尾字符的j变量就递减,如果从haystack索引到的字符与当前使用j变量从needle中索引到的尾字符不等,j变量就要恢复成needle的最大索引值nLen,以让接下来从haystack中的匹配扫描重新从needle的末字符开始,显然只有在之前匹配到尾字符后j变量的值才会改变,后面匹配不上了才需要重置j变量的值成nLen,而不是每次循环中不管之前有没有匹配到只要本次没匹配到就重置j为nLen,这样在之前没匹配到的情况下,j仍旧等同为nLen,此时这步操作就是冗余的,带来不必要的性能消耗。
在这里插入图片描述

4.最终实现

//在字符串haystack中查找字符串needle最后一次出现的位置,
//找到返回needle在haystack中的索引值,否则返回0
//(注:Pascal/Delphi中string类型的索引从1开始).
function strrstr(const haystack, needle: string): Integer;
var i, j, nLen: Integer;
label ISOVER;
begin
  strrstr:= 0;
  i:= Length(haystack);
  nLen:= Length(needle);
  j:= nLen;
  if(i = 0) or (j = 0) or (j > i) then 
  	Exit;

  repeat
    if haystack[i] = needle[j] then
    begin
       GOTO ISOVER;
       repeat
         if haystack[i] = needle[j] then
         begin
           ISOVER:
           if j = 1 then
           begin
             strrstr:= i;
             Exit;
           end;
           Dec(j);
         end
         else
         begin
           j:= nLen;
           Break;
         end;
         Dec(i);
       until i = 0;
    end;
    Dec(i);
  until i = 0;
end;

5.运行结果

😃
在这里插入图片描述

举报

相关推荐

0 条评论