@denny
Tatsache! Nicht schlecht. Vorallem liefert Tic/Toc schnelle Zeiten.
Jedenfalls schneller als meine Methode.
Gibt es evtl eine noch effizientere Methode? Ich frage aus 2 Gründen:
Zum Einen möchte ich später diesen Algorithmus nach C portieren, zum Anderen wundert es mich, dass man einen Vektor-Vergleich (also finde A in B, wobei length(A)<length(B)) mit einem String-Befehl löst.
(Ich habe es vergeblich mit "ismember" und "intersect" versucht.)
Das STRFIND auch mit nicht-CHAR-Arrays arbeitet ist sehr praktisch und sollte in der Dokumentation deutlicher betont werden.
Eine Schwachstlle ist "[0 A]" und [A, 0]" für sehr große Vektoren A: Es werden im schlimmsten Fall (2*(length(A)+1)*8) Bytes im Speicher blockiert. Das ist zwar nur temporär, wenn der Rechner aber den RAM-Inhalt auf die Platte schreiben muss, wird es unerträglich langsam.
Ich vermute für riesige A ist dies sicherer (also schneller):
Code:
%%%%%%%%%%%% VORSICHT: BUGS! Siehe folgende Nachrichten!
Laenge = 4
A = (rand(1, 1e8) > 0.5); % Beispiel Daten
Start = strfind(A, [0ones(1,Laenge)]);
ifall(A(1:Laenge) == 1)
Start = [1, Start];
end
Ende = strfind(A, [ones(1,Laenge)0])+Laenge-1;
ifall(A(end-Laenge+1:end) == 1)
Ende = [1, Ende];
end
@denny:
Dein neuer Algo findet nur das erste Paar. Weitere Folgen, die auch die Bedingungen erfüllen, werden nicht angezeigt.
@Jan:
Ich komme nicht auf das gleiche Ergebnis:
Das leichteste, was ich beheben konnte war, auf den Lösungsvektor "Start" 1 zu addieren. Dann klappts.
Aber der "Ende"-Vektor fängt mit 1 an? Und das Ende einer letzten Folge ist mir auch nicht ersichtlich (siehe Ende(end))
habe kleinen Fehler beim Abziehen gemacht, im Beispiel kommen ja 5 Einsen hintereinander, habe ja darauf getestet, und deswegen übersehen dass mit 4 Einsen es nicht funktioniert hat.
Zusätzlich hätte ich eine 2. Frage passend dazu, an Alle:
Wie kann ich am besten/effizientesten/einfachsten nun alle Bereiche in Vektor A auf Null setzen, die diese Bedingung (Mindestlänge) nicht erfüllen? Oder andersherum formuliert: Wie kann ich einen neuen Vektor A_neu erstellen, der in den zurückgegebenen Intervallen -also von Start bis Ende- true ist, und überall anders false?
Ich habe das leider nur mit einer For-Schleife lösen können:
Du hast Denny geschrieben, dass es "einen Fehler gibt" - es ist immer praktisch auch zu lesen, wie die Fehlermeldung denn lautet.
Die gepostete FOR-Schleife läßt sich beschleunigen: Bisher ist "A_neu" ein DOUBLE Vektor, in den Du "true"-Werte schreibst. Diese werden intern von LOGICAL (eigentlich ein uint8) nach DOUBLE gecastet (heißt das so auf Deutsch?). Schneller wäre es, gleich ein LOGICAL Vektor zu erstellen:
Ausserdem habe ich die Antwort der Funktion(!) TRUE abgespeichert, weil ein Funktionsaufruf einen größeren Overhead hat, als das Kopieren einer Variable.
Eine andere Lösung als die FOR-Schleife wäre CUMSUM:
Wie kann ich nun die vielen Start&Ende-Paare, aus den jeweiligen Vektoren "Start" und "Ende" in einem Schritt zur Adressierung verwenden?
Zur Zeit gehe ich noch mit einer Schleife durch, und erhalte einzelnd ein Start&Ende-Paar, was ich zur Adressierung verwende:
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.