Anzeige:
Ergebnis 1 bis 3 von 3

Thema: Perl: Doppelte aus Array entfernen

  1. #1
    Registrierter Benutzer
    Registriert seit
    17.11.2006
    Beiträge
    42

    Perl: Doppelte aus Array entfernen

    Hallo,

    ich habe ein Problem mit dem ich nicht so recht weiterkomme.

    Ich lese aus einer Datei mehrere tausend Telefonnummern in ein Array ein.

    Aus diesem Array sollen doppelte Werte und leere Werte entfernt werden, aber gleichzeitig soll festgehalten werden, welche Werte doppelt enthalten sind.

    Ich habe dafuer zwar ein funktionierendes Script, aber es ist ein riesiger Aufwand, vor allem wenn man bedenkt, dass es sich um ein paar tausend Daten handelt und um das Ziel zu erreichen mehrere Arrays mit den gleichen Daten gefuellt werden muessen (bei sort muss lt Beschreib8ung immer ein neues Array verwendet werden)

    Hier mal mein script. Ich habe es auf der Konsole ausgefuehrt und lasse mir die Ergebniss nach der Operation anzeigen, damit ich weiss, ob alles klappt.

    Ich denke es muesste fuer dieses Script eine Optimierung geben, die mir als Non-perl-profi aber nicht einfaellt.
    Hat jemand Optimierrungsvorschlaege?
    Mich stoert vor allem, dass ich bei grossen Datenmenegen (z.B. 10.000) mehrere Arrays mit den gleichen Daten habe, was ja irgendwo auch unnoetigen Speicherplatz verbraucht.

    Hier mein Script:
    Code:
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    # Daten einlesen
    my @Zeilen = ('49721509666000','17024470924','4918059701116000','491771784144','17078850469','49721509666000','','284765769609','','17024470924','49721509666000');
    
    # Sortieren und zur Pruefung auf Console ausgeben
    my @neuzeilen1 = sort(@Zeilen); 
    
    # Doppelte in separates Atrray einstellen und im Hauptarray leeren
    my $oldwert = '';
    my @doppelte;
    for(my $iiz=0;$iiz<@neuzeilen1;$iiz++)
       {
       if($oldwert eq $neuzeilen1[$iiz])
          { 
          push(@doppelte,$neuzeilen1[$iiz]); 
          $neuzeilen1[$iiz] = '';
          }
       else
          { $oldwert = $neuzeilen1[$iiz]; }
       }
       
    # Hauptarray neu sortieren um alle leeren Felder am Anfang zu haben und Kontrollausgabe
    my @neuzeilen2 = sort(@neuzeilen1); 
    
    my $anzd;
    for (@doppelte)
       {  
       if($_ ne '')
          { last; }
       else
          { $anzd++; }
       }
    
    # leere Doppelte entfernen
    print "Anzahl leere doppelte: $anzd\n";
    splice(@doppelte,0,$anzd);
    
    print "Doppelte ausgeben\n";
    for (@doppelte)
       { print 'X: '.$_."\n"; }
    print "\n\n";
    
    # Anzahl leere Arrays in Hauptarray feststellen
    my $anzn;
    for (@neuzeilen2)
       {  
       if($_ ne '')
          { last; }
       else
          { $anzn++; }
       }
    
    # Leere Arrays in Hauptarray entfernen
    print "Anzahl leere doppelte: $anzn\n";
    splice(@neuzeilen2,0,$anzn);
    
    print "Hauptarray ausgeben\n";
    for (@neuzeilen2)
       { print 'X: '.$_."\n"; }
    print "\n\n";
    
    exit(1);
    Also wie gesagt: Das Script funktioniert. Es geht nur um die Optimierung von Speicherplatz und Rechenleistung bei grossen Mengen

    Chris

  2. #2
    Registrierter Benutzer
    Registriert seit
    05.02.2006
    Beiträge
    116
    Code:
    #!/usr/bin/perl
    
    # die folgenden Zeilen sollten Pflicht in jedem Programm sein!
    use strict;
    use warnings;
    
    my @telefonnummern = ( '...' ); # riesen Array mit Telefonnummern
    
    # Ein Hash ist Mittel der Wahl wenn man bei irgendwelchen Werten die
    # Werte immer nur einmal vorkommen dürfen. Die Schlüssel eines Hashs
    # müssen eindeutig sein.
    my %unique_tel;
    
    # Die Telefonnummer ist der Schlüssel des Hashs und als Wert bekommt
    # man die Anzahl
    $unique_tel{ $_ }++ for @telefonnummern;
    
    my @nur_einmal = grep{ $unique_tel{ $_ } == 1 }keys %unique_tel;
    my @mehrmals  = grep{ $unique_tel{ $_ } > 1 }keys %unique_tel;
    Das mal als Ansatz. Es ist natürlich effizienter, wenn man nicht erst alles in ein Array einliest und am Ende wieder Arrays haben möchte, sondern alles direkt verarbeiten kann und maximal den Hash braucht.

    So könnte es aussehen (ohne Kommentare), wenn man die Telefonnummern aus einer Datei einliest und dann nur die Telefonnummern ausgibt.

    Code:
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    my %tel_nummern;
    open my $in_h, '<', 'datei_mit_telnummern.txt' or die $!;
    while ( my $line = <$in_h> ) {
    }
    close $in_h;
    
    for my $nummer ( keys %tel_nummern ) {
        print "Tel: $nummer\n";
    }

  3. #3
    Registrierter Benutzer
    Registriert seit
    17.11.2006
    Beiträge
    42
    Danke fuer Deine Hinweise!

    Hat mir sehr geholfen. Habe das Problem jetzt geloest. Muss es allerdings doch erst einlesen, so wie in Deinem ersten Beispiel, da vorher noch weitere Arbeiten getan werden muessen.

    Danke!

    Vagabundo

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •