Verfasst am: 28.03.2011, 11:22
Titel: Liste durchlaufen - neue Elemente in 2. Liste einfügen
Hallo Leute,
ich stehe vor folgendem Szenario. Ich hab eine laaaange unsortierte Liste (A) in der die Werte mehrmals vorkommen. Nun hatte ich vor diese Liste durchzulaufen und jedes neue Element in eine neue Liste (B) hinzufügen, damit ich eine sortierte Liste habe, in der jedes Element nur einmal vorkommt.
Mein Code sieht wie folgt aus:
Code:
function result = sortieren(Datensatz) % 1. Eintrag hinzufügen, damit neue Liste entsteht
result = cell({Datensatz{1,2}{1,1}});
yes = 0;
% durchlaufe Liste ab dem 2. Eintrag for i = 2:size(Datensatz{1,2},1)
Funktionieren tut es schon und dauert natürlich sehr lange, da ich mit jedem Eintrag in der unsortieren Liste (A) die neue Liste (B) durchlaufen muss... vllt. habt ihr Verbesserungsvorschläge.
Doch jetzt kommts zum eigentlichen Problem. Ich will mir die Indizes der Elemente auch speichern, am besten in der neuen Liste B gleich neben dem Element. Die Indizes sind ja über die for-Schleife mit 'i' zu holen nur bekomm ich das nicht hin. Die Cell-Matrix macht dann komische Dinge und ich komm einfach nicht mit den Klammern {}() klar, usw...
Habt ihr ne Idee wie man das verwirklichen könnte?
angeschaut?
Der sollte eigentlich deinen Code ersetzen können.
p.s.:
Die Klammern {} sind nur bei einer cell interessant weil du damit auf den Inhalt einer cell zugreifst. Mit () funktioniert das bei einer cell nicht.
_________________
Verfasst am: 28.03.2011, 14:21
Titel: Re: Liste durchlaufen - neue Elemente in 2. Liste einfügen
Hallo friesen,
Dein Programm läßt sich deutlich beschleunigen:
1. Pre-allocation: Erstelle am Anfang ein CELL-Array mit der maximal möglichen Länge und schneide die ungenutzten CELL-Elemente am Schluß wieder ab. Ein Array wachsen zu lassen verbraucht enorm viel Speicher und kann locker 10^6 mal langsamer sein als ein bestehendes Array aufzufüllen.
2. Der immer und immer wiederholte Zugriff auf "Datensatz{1,2}" vergeudet Zeit. Besser wäre es, Du kopierst einmal dieses Object heraus, sodass nicht in jedem Aufruf wieder zunächst das CELL-Element {1, 2} im Speicher gesucht werden muss.
3. Noch zeitraubender ist der wiederholte Zugriff auf "Datensatz{1,2}{i,1}". Besser einmal kopieren, als tausende Male suchen.
Manche Dinge verstehe ich aber nicht: Bisher sortiert Dein Programm gar nicht, im Widerspruch zur Beschreibung.
Und "result = cell({Datensatz{1,2}{1,1}});" bleibt mit ein Rätsel. Meinst Du: "result = Datensatz{1,2}(1)" ?
Data = Datensatz{1, 2};
nData = size(Data, 1);
result = cell(nData, 2); % Pre-allocate
% 1. Eintrag hinzufügen, damit neue Liste entsteht
counter = 1;
result{1, 1} = Data{1};
result{1, 2} = 1;
for i = 2:nData
iData = Data{i};
yes = 0;
for j = 1:size(result,1) ifisequal(result{j,1}, iData)
yes = 1;
break; % Verlasse "for j" beim ersten Treffer! end end
if yes == 0
counter = counter + 1;
result{counter, 1} = iData;
result{counter, 2} = i;
end end
result = result(1:counter);
% Es gibt keinen Grund lokale Variablen am Ende einer Funktion % mit CLEAR zu löschen!
"isequal(result{j,1}, iData)" hat einen Vorteil gegenüber "result{j,1} == iData": Letzteres testet elementweise und wenn beide Operanden unterschiedliche Größe haben, scheitert der Vergleich. Wenn aber alle Elemente von "Datensatz{1, 2}" gleich groß sind, ist ein CELL-Array eine ausgesprochen ungeschickte Wahl der Datenspeicherung! Ein mehrdimensionales numerisches Array wäre dann dramatisch effizienter.
Aber wie Peter schon sagte: Wahrscheinlich geht das mit UNIQUE enorm viel schneller und zudem ist die Ausgabe dann bereits sortiert. Um dies zu klären müsstest Du noch angeben was "laaange" genau heißt: 1.000, 1.000.000 oder mehr? Und welchen Type haben die Elemente der zu sortierenden CELL?
danke für die Verbesserung. Mit ein paar Anpassungen funktioniert es wie sollte. Nur versteh ich nicht was 'result = result(1:counter);' bezwecken soll. Damit willst du doch bestimmt das CELL-Array kürzen. Geht aber nicht.
Nur versteh ich nicht was 'result = result(1:counter);' bezwecken soll. Damit willst du doch bestimmt das CELL-Array kürzen. Geht aber nicht.
"Geht aber nicht" ist eine vage Fehlerbeschreibung.
Die Zeile stammt aus einer Version, bei der ich den Index noch nicht eingebaut hatte. Verbesserung:
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.