2016-10-07 2 views
2

Ich möchte zählen, wie oft ein String in einem anderen String in Pascal Script auftritt, wie im folgenden Beispiel gezeigt.Pascal Script Anzahl der Male, die eine Zeichenfolge in einer anderen Zeichenfolge auftritt

Ich habe die Antwort auf Delphi: count number of times a string occurs in another string gesehen, aber es gibt keine PosEx Funktion in Pascal Script.

MyString := 'Hello World!, Hello World!, Hello World!, Hello World!'; 

Wenn ich die Anzahl der Male Hello oder World tritt hier zählen, sollte das Ergebnis 4.

sein, wenn ich die Anzahl der , (Komma) hier auftritt zählen, sollte das Ergebnis 3 sein.

UPDATE

Die folgende Funktion funktioniert, aber es Kopien String wieder auf eine neue Variable gegeben und löscht Teile String s, so funktioniert es langsam.

function OccurrencesOfSubString(S, SubStr: String): Integer; 
var 
    DSStr: String; 
begin 
    if Pos(SubStr, S) = 0 then 
    Exit 
    else 
    DSStr := S; 
    Repeat 
    if Pos(SubStr, S) <> 0 then 
    Inc(Result); 
    Delete(DSStr, Pos(SubStr, DSStr), Length(Copy(DSStr, Pos(SubStr, DSStr), Length(SubStr)))); 
    Until Pos(SubStr, DSStr) = 0; 
end; 
+0

Dies ist kein Code-Schreibdienst. Haben Sie sich überhaupt darum bemüht? Sie können es ohne PosEx machen; Es wurde Jahrzehnte lang gemacht, bevor PosEx überhaupt existierte. –

+0

Ja, aber ich konnte meinen Code nicht veröffentlichen, da er nicht wie erwartet funktioniert. – GTAVLover

+3

Dann poste deinen Code, der nicht funktioniert, und * stelle eine spezifische Frage * zu diesem Code. Auch hier handelt es sich nicht um einen Codewriting-Service, bei dem Sie Ihre Anforderungen und die Sprache Ihrer Wahl posten und jemand Code für Sie erstellt. –

Antwort

3

Ihre Implementierung ist im Allgemeinen korrekt.

Es gibt einige Optimierungen vorgenommen und nutzlosen Codes werden entfernt werden:

  • Der zweite Test für if Pos(SubStr, S) <> 0 (innerhalb repeat) sinnlos. Es ist immer wahr. Sie testen S, die bereits am Funktionsstart getestet wurde. Und die DSStr ist bereits in der until getestet.
  • Sie sollten Pos(SubStr, DSStr) zu einer Variablen speichern, um sie nicht mehrmals aufzurufen.
  • Length(Copy(DSStr, Pos(SubStr, DSStr), Length(SubStr))) ist eigentlich das gleiche wie Length(SubStr).
  • Keine Notwendigkeit, die S zu DSStr zu kopieren. Sie können direkt mit dem S arbeiten. Es ist By-Value-Parameter, also ändern Sie nicht die Variable, die Sie verwenden, um die Funktion aufzurufen.
  • Ersetzen Sie die ursprüngliche Pos(SubStr, S) = 0 überprüfen Sie mit der gleichen Prüfung in der Schleife, um eine Pos Aufruf zu speichern.

optimierte Version des Codes:

function OccurrencesOfSubString(S, SubStr: String): Integer; 
var 
    P: Integer; 
begin 
    Result := 0; 
    repeat 
    P := Pos(SubStr, S); 
    if P > 0 then 
    begin 
     Inc(Result); 
     Delete(S, P, Length(SubStr)); 
    end; 
    until P = 0; 
end; 

Aber eigentlich mit dem Inno Setup StringChange function (die Delphi nicht hat), man muss sich jeder Algorithmus nicht codieren.

function OccurrencesOfSubString(S, SubStr: String): Integer; 
begin 
    Result := StringChange(S, SubStr, ''); 
end; 

Dies wurde durch die @RobertFrank's answer to Delphi: count number of times a string occurs in another string inspiriert.

Während die Verwendung der StringChange ineffizient aussieht (da es erhebliche Nebenwirkungen hat), ist es tatsächlich schneller. Wahrscheinlich, weil es in Pascal, nicht in Pascal Script implementiert ist.

Getestet mit 3.000.000 Anrufen:

OccurrencesOfSubString('Hello World!, Hello World!, Hello World!, Hello World!', 'Hello') 
  • Mit StringChange: 11 Sekunden
  • Meine optimierte Version des Codes: 49 Sekunden
  • Ihr Original-Code: 99 Sekunden

Obwohl für einige Anrufe alle Implementierungen gut genug sind.

+0

Vielen Dank! funktioniert !, Da ich nicht genug Zeit hatte, wurde ich spät dran, meine Frage mit meiner Funktion zu aktualisieren. :-( – GTAVLover

+0

Vielen Dank für eine hervorragende Hilfe! Wenn ich direkt mit dem 'S' arbeite, sind nicht die Inhalte von' S' verloren, nachdem Sie Ihre optimierte Version meiner Funktion aufgerufen haben? Was meinten Sie mit By-Value? – GTAVLover

+0

Wenn Sie den Parameter als 'S: string' deklarieren, wird er nach Wert übergeben (durch Kopieren), so dass jede Änderung des' S' in der Funktion an einer Kopie der Zeichenfolge vorgenommen wird und die verwendete Variable nicht beeinflusst Die Funktion kann auch mit einer konstanten Zeichenkette aufgerufen werden - Im Gegensatz zu einem Parameter, der als 'var S: string' deklariert ist - Dies wird als Referenz übergeben Jede Änderung am' S' ändert die Variable wird verwendet, um die Funktion aufzurufen - und folglich können Sie keine konstante Zeichenkette für den Parameter verwenden, da die Konstante nicht geändert werden kann –

Verwandte Themen