![]() |
"Überlappungen" zwischen zwei Strings
Mein Covfefe ☕ scheint heute noch nicht zu wirken.
Angenommen ich habe zwei Strings
Delphi-Quellcode:
und
Eins Zwo Hallo Welt
Delphi-Quellcode:
. Ich möchte die zwei Strings konkatenieren, allerdings "ohne das doppelte mittendrin":
Hallo Welt Guten Tag
Code:
Gibt es da einen trivialen Lösungsansatz? Schwere Geschütze mit Queues/Stacks oder regulären Ausdrücken wollte ich vermeiden.
Eins Zwo Hallo Welt
Hallo Welt Guten Tag => Eins Zwo Hallo Welt Guten Tag |
AW: "Überlappungen" zwischen zwei Strings
Ohne das doppelte mitten drin oder allgemein doppelte Wörter?
|
AW: "Überlappungen" zwischen zwei Strings
Auf Anhieb fällt mir nur das naive Vorgehen ein:
(*) diese Stelle kann man ggf. beschleunigen, wenn man ähnliche Tricks anwendet wie bei Knuth-Morris-Pratt. Damit sollte man dann auf eine lineare Worst-Case-Laufzeit kommen, die so erstmal nicht garantiert ist. |
AW: "Überlappungen" zwischen zwei Strings
Wie wäre es, wenn man die Strings übereinander legt und prüft, ob die überlappenden Buchstaben/Teilstring gleich sind. Wenn ja, hat man die Überschneidung. Wenn nein, verschiebt man den 2. String um eine Stelle und prüft wieder. Da böte sich vielleicht eine rekursive Lösung an.
Code:
Eins Zwo Hallo Welt
Hallo Welt Guten Tag Eins Zwo Hallo Welt Hallo Welt Guten Tag Eins Zwo Hallo Welt Hallo Welt Guten Tag ... Eins Zwo Hallo Welt Hallo Welt Guten Tag |
AW: "Überlappungen" zwischen zwei Strings
Vorab eine blöde Frage:
Kann auch folgendes vorkommen: 1. Eins Zwo Hallo Welt 2. Drei Hallo Guten Tag = keine Überlappung. Oder: 1. Eins Zwo Hallo Welt Drei 2. Hallo Welt Guten Tag = Eins Zwo Hallo Welt Guten Tag Drei Oder ist es immer so, das der Beginn der möglichen Überlappung am Anfang des zweiten Strings definiert ist? |
AW: "Überlappungen" zwischen zwei Strings
Zitat:
|
AW: "Überlappungen" zwischen zwei Strings
Irgendwie so?
Delphi-Quellcode:
Je nach Anforderung muss man die Schleife umdrehen.
uses Math, StrUtils;
Length1 := Length(Text1); // man sollte LeftStr und RightStr unten ersetzen durch das wesentlich effizientere Copy, wofür man das hier braucht, dafür bin ich aber zu faul for i := 1 to Min(Length(Text2), Length1) do if RightStr(Text1, i) = LeftStr(Text2, i) then Exit(Text1, Copy(Text2, i, High(Integer))); raise Exception.Create('geht nicht'); |
AW: "Überlappungen" zwischen zwei Strings
Dann würde ich erstmal die Methode von mir (bzw. die von Nersgatt, das ist ja identisch) nehmen. Kann man natürlich in der Hinsicht optimieren, dass das erste "Übereinanderlegen" so anfängt, dass der untere String rechtsbündig mit dem ersten ist. Vorher ergibt die Suche ja keinen Sinn.
Und wenn eine gute (d.h. lineare) Worst-Case-Laufzeit wichtig ist (Probleme machen bei solchen Ansätzen Strings wie "abababababaC"), dann schau dir ![]() "Bruteforce" wäre natürlich eine Schleife mit AnsiStartStr und AnsiEndStr (oder vergleichbaren Ansätzen, siehe Beitrag von Redeemer). Bei kurzen Strings ist das aber sicherlich vertretbar, d.h. wenn die Programmierkosten hier relevanter sind als eine gute Laufzeit. ;-) |
AW: "Überlappungen" zwischen zwei Strings
Zitat:
Vorher schaue ich aber ob ich nicht vielleicht doch um den Abgleich drum herum komme 😎 |
AW: "Überlappungen" zwischen zwei Strings
Zitat:
Habe damals meine Diplomarbeit darüber geschrieben, daher reite ich da manchmal gerne drauf rum. :lol: Ein kleines Animationsprogramm, was z.B. auch die Anzahl der Vergleiche bei verschiedenen Verfahren ausgibt, gibt es auf meiner ![]() Aber wenn ich das nochmal überdenke: Der Boyer-Moore-Ansatz könnte hier (wieder etwas modifiziert) auch funktionieren ... (und der ist leichter zu implementieren, imho). |
AW: "Überlappungen" zwischen zwei Strings
Ich würde das nicht mal Zeichen genau machen in dem Fall.
Ich würde die Strings splitten und dann Wort für Wort vergleichen so lange es gleich ist. 1. Den ersten String zerteilen (Wortweise) 2. Dies von hinten nach vorne durchgehen und mit dem zweiten String (Wortweise, von vorne nach hinten) vergleichen 3. Sobald das mit den Worten nicht mehr passt, Stelle merken und aus der Schleife aussteigen. 4. Strings zusammenfügen. |
AW: "Überlappungen" zwischen zwei Strings
Zitat:
![]() Zitat:
|
AW: "Überlappungen" zwischen zwei Strings
ich würde den ersten string von hinten und den zweiten von vorne nehmen - ich weiss, hört sich jetzt schweinisch an ;)
1. Erstes Zeichen vom zweiten String unter letztes Zeichen vom ersten legen 2. Überlappung vergleichen 3. Bei Gleichheit zweiten String um eines nach vorne schieben, goto 2 4. Bei Ungleichheit hat man den überlappenden Teil gefunden |
AW: "Überlappungen" zwischen zwei Strings
Zitat:
Deine Methode würde in diesem Beispiel nur "ei" als Überlappung finden, denn der folgende Schleifendurchlauf mit "rei" und "ein" sorgt für den Abbruch. Gewünscht wäre aber vermutlich "eins zwei drei".
Code:
Auch wenn das gekünstelt ist und die "Wortbedingung" hier auch verletzt ist. ;-)
ich zähle eins zwei drei
eins zwei drei wurde gezählt Edit: bzw. würde man gar keine Überlappung finden, weil schon "i" und "e" ungleich sind. |
AW: "Überlappungen" zwischen zwei Strings
Mit TStringHelper geht das recht überschaubar:
Delphi-Quellcode:
function ConcatNoOverlap(const A, B: string): string;
var I: Integer; begin for I := Min(A.Length, B.Length) downto 1 do if string.Compare(A, A.Length - I, B, 0, I) = 0 then Exit(A.Remove(I-1) + B); Result := A + B; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:00 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz