我正在使用德爾福2007年,並想知道是否有一個簡單的方法來計算一個字符串發生在另一個字符串中的次數。我可以使用哪些內置函數?德爾福:計數一個字符串發生在另一個字符串的次數
例子:「你好嗎」
- 「如何」在字符串中出現一次
- 「do」在字符串「你好嗎?」中出現兩次。
我正在使用德爾福2007年,並想知道是否有一個簡單的方法來計算一個字符串發生在另一個字符串中的次數。我可以使用哪些內置函數?德爾福:計數一個字符串發生在另一個字符串的次數
例子:「你好嗎」
function Occurrences(const Substring, Text: string): integer;
var
offset: integer;
begin
result := 0;
offset := PosEx(Substring, Text, 1);
while offset <> 0 do
begin
inc(result);
offset := PosEx(Substring, Text, offset + length(Substring));
end;
end;
一個我見過這樣做的最聰明的方法:
{ Returns a count of the number of occurences of SubText in Text }
function CountOccurences(const SubText: string;
const Text: string): Integer;
begin
if (SubText = '') OR (Text = '') OR (Pos(SubText, Text) = 0) then
Result := 0
else
Result := (Length(Text) - Length(StringReplace(Text, SubText, '', [rfReplaceAll]))) div Length(subtext);
end; { CountOccurences }
是的,這是一個非常聰明的方法。實際上,RRUZ昨天發佈了這個方法作爲答案,但之後由於某種原因,他刪除了它。我對他的問題發表的評論是*確實,這是一個「特別版」。然而,從性能角度來看,這是遠遠不夠理想的,恐怕...... *說實話,我認爲沒有理由使用這種方法的時候,有更高性能的方法,而不是更復雜。不過,如果我對RRUZ沒有感到不好,我會給你一個+1 ... – 2011-03-11 14:25:41
好吧,無論如何,我給你+1。由於你「只」在代表1683年,你看不到已刪除的帖子。但是如果RRUZ取消刪除他的問題,我保證我也會給他一個+1。 – 2011-03-11 14:31:03
聰明但緩慢,浪費記憶。 – 2011-03-11 21:32:23
如果你發現自己經常在大正文文本的搜索出現次數和性能成爲問題,你可以試試Boyer-Moore search algorithm。
最壞情況下找到所有出現 文本大約需要3N 比較
在Delphi中的實現可以發現在我們自己的SO here
我需要三個快速大字符串 功能:快速搜索,快速搜索 並替換,並快速計數 字符串中的子串。
+1瞭解Boyer-Moore搜索的內容。 – 2011-03-11 21:32:44
uses
StrUtils;
function Occurrences(const Substring, Text: string;
const ignoreUppercase: Boolean = false): Integer;
var
inSubstring, inText: string;
inPos: Integer;
begin
Result:= 0;
if (Substring = '') or (Text = '') then
Exit;
if ignoreUppercase then
begin
inSubstring:= AnsiLowerCase(Substring);
inText:= AnsiLowerCase(Text);
end
else
begin
inSubstring:= Substring;
inText:= Text;
end;
inPos:= 1;
repeat
inPos:= posEx(inSubstring, inText, inPos);
if inPos > 0 then
begin
Inc(Result);
inPos:= inPos + Length(inSubstring);
end;
until inPos = 0;
end;
請包括一些描述或對代碼的解釋,而不是僅僅回答一段代碼片段。 – davidcondrey 2014-07-15 21:22:42
這看起來像接受答案的變體。你能解釋爲什麼這是不同的,這樣做的好處是什麼? – andrewsi 2014-07-15 21:39:16
在這種情況下使用循環「重複」更優雅,因爲搜索必須至少保留一次。 – GoodMan 2014-07-28 17:22:32
第二PosEx可以寫 「偏移:= PosEx(串,文字,膠印+長度(串));」 如果你不關心復發子。 ;) – 2011-03-10 20:27:34
@ A.Bouchez:是的,這是非常真實的。我甚至會說你應該使用子字符串的實際長度*特別是*如果你關心像'Occurrences('ddd','dddddddd')'這樣的(病態)輸入。我改變了這一點。當然,對於性能來說,在循環之前保存'len:= length(Substring)'是一個好主意(或者編譯器足夠聰明,可以自己完成這種優化?)。 – 2011-03-10 20:34:21
+1我可能會使用一個var並在其中存儲SubString的長度以避免重複調用Length,但由於Length實際上只是從@SubString讀取一個負偏移量,所以它可能不會有太大的性能影響。 :) – 2011-03-10 20:38:29