2011-03-10 22 views
20

Delphi 2007 kullanıyorum ve bir dizenin başka bir dizede kaç kez geçtiğini saymanın basit bir yolu olup olmadığını merak ediyorum. Kullanabileceğim yerleşik işlevler var mı?Delphi: başka bir dizgede bir dizgenin kaç kez oluştuğunu saymak

Örnekler: "? Nasılsın"

  • dize kere geçer "Nasıl"
  • "Yap", "Nasıl Yaparsınız?" Dizesinde iki kez oluşur. Şimdiye kadar bunun için gördüğüm en zeki yollarından

cevap

37
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; 
+2

2 PosEx yazılmış olabilir "offset: = PosEx (alt dize, Metin, + uzunluğunu (alt dize) ofset);" Eğer tekrarlayan alt dizeleri umurumda değil eğer. ;) –

+1

@ A.Bouchez: Evet, bu çok doğru. Hatta alt tabakaların gerçek uzunluğunu kullanmanız gerektiğini bile söyleyeyim * özellikle * eğer (Patolojik) girdiler varsa, 'Geçişler (' ddd ',' dddddddd ') 'gibi. Bunu değiştirdim. Tabii ki, performans için döngüden önce len: = uzunluk (Substring) 'yi kaydetmek iyi bir fikirdir (veya derleyici bu optimizasyonu kendi başına yapacak kadar akıllı mıdır?). –

+1

+1 Muhtemelen bir var kullanmalı ve SubString uzunluğunu Uzunlukta yinelenen çağrıları engellemek için içerdim. Ancak, Uzunluk gerçekten de sadece bir OfSubString'den bir negatif sapma okunduğundan, muhtemelen bir performans artışı değil. . :) –

8

Bir:

{ 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 } 
+0

Evet, bu çok akıllıca bir yol. Aslında, RRUZ bu yöntemi bir cevap olarak dün yayınladı, ama bir sebepten dolayı silindi. Onun sorusuna verdiğim yorum şöyle oldu: "Eh, bu bir" özel baskı ", gerçekten de. Performans-bilge, bununla birlikte, ideal olmaktan uzak, korkuyorum ... * Dürüst olmak gerekirse, daha fazla performans göstermeyen daha fazla performans olduğunda, bu yöntemi kullanmanın bir sebebi olmadığını düşünüyorum. Yine de, RRUZ için kötü hissetmemiş olsaydım size bir +1 verirdim ... –

+0

Size bir +1 veririm. "Yalnızca", 1683 numaralı temsilci bulunduğundan, silinmiş yayınları göremezsiniz. Ama RRUZ sorusunu geri almazsa, söz veriyorum ona bir +1 vereceğim. –

+1

Zeki, ama yavaş ve hafızayı boşa harcıyor. Boyer-Moore aramasının ne olduğunu bilmek için –

4

kendinizi sık metnin bir büyük vücutta tekrarlarını arama bulmak ve performans bir duruma gelirse Sorun, Boyer-Moore search algorithm deneyebilirsiniz.

bir metin yaklaşık 3n karşılaştırmaları

ihtiyacı içinde Delphi An uygulama bizim çok ihtiyacım SO here

sahibi bulunabilir tüm tekrarlamalarını bulmak için en kötü durum üç hızlı geniş-dizeleri fonksiyonları: hızlı arama, hızlı arama ve bir dize alt dizeleri ve hızlı sayısı.

+1

+1 numaralı telefonu arayın. –

1

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; 

+1

Lütfen yalnızca kod snippet'ini cevaplamak yerine kodunuzun açıklamasını veya açıklamasını ekleyin. – davidcondrey

+1

Bu, kabul edilen yanıtta bir varyasyona benziyor. Bunun neden farklı olduğunu ve bunun bu şekilde yapmanın yararlarını açıklar mısınız? – andrewsi

+0

Döngü "tekrar" kullanımı bu durumda daha zariftir, çünkü arama en az bir kez yapılmalıdır. – GoodMan

İlgili konular