WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Liste durchlaufen - neue Elemente in 2. Liste einfügen

 

friesen
Forum-Anfänger

Forum-Anfänger


Beiträge: 21
Anmeldedatum: 08.12.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 28.03.2011, 11:22     Titel: Liste durchlaufen - neue Elemente in 2. Liste einfügen
  Antworten mit Zitat      
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)
   
    % durchlaufe 2. Liste
    for j = 1:size(result,1)                        
       
        % frage ab ob vorhanden
        if result{j,1} == Datensatz{1,2}{i,1}            
            yes = 1;  
        end  
    end
   
    % wenn nicht vorhanden, fuege am Ende hinzu
    if yes == 0
        result(size(result,1)+1,:)={[Datensatz{1,2}{i,1}]};
    end
   
    % yes wieder zuruecksetzen
    yes = 0;
end

% lösche Lokalvariablen
clear i j yes;    
 


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?


Grüße
Private Nachricht senden Benutzer-Profile anzeigen


_Peter_
Moderator

Moderator


Beiträge: 537
Anmeldedatum: 08.12.10
Wohnort: ---
Version: 7.10, 2010a
     Beitrag Verfasst am: 28.03.2011, 12:36     Titel:
  Antworten mit Zitat      
Hallo friesen,

Hast du dir schonmal den Befehl
Code:

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.
_________________

Gruß
Peter
_________________
goMatlab-Knigge - dran gehalten?!
Schon in den FAQ gesucht? Oder der MATLAB Hilfe?
Ist vielleicht bei den Skripten oder den Tutorials was für dich dabei?
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 28.03.2011, 14:21     Titel: Re: Liste durchlaufen - neue Elemente in 2. Liste einfügen
  Antworten mit Zitat      
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)" ?

Hier mal eine beschleunigte Version:
Code:

function result = sortieren(Datensatz)

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)                        
        if isequal(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?

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
friesen
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 21
Anmeldedatum: 08.12.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 29.03.2011, 14:20     Titel:
  Antworten mit Zitat      
Hi Jan,

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.

Wie kriegt man dass denn jetzt hin?


Grüße
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 30.03.2011, 01:37     Titel:
  Antworten mit Zitat      
Hallo friesen,

Zitat:
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:
Code:
result = result(1:counter, :);

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
friesen
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 21
Anmeldedatum: 08.12.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 30.03.2011, 09:45     Titel:
  Antworten mit Zitat      
Ja sorry. Hatte mich nicht richtig ausgedrückt.

Es funktioniert aber wunderbar. Danke dir!!!



Grüße
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

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
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

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.