Schrift
[thread]8957[/thread]

Operationen auf Arrays -Frage-: Fragen zu shift und co. (Seite 2)



<< |< 1 2 >| >> 17 Einträge, 2 Seiten
sKy
 2007-05-02 23:05
#76353 #76353
User since
2006-12-05
10 Artikel
BenutzerIn
[default_avatar]
Hi ,
hier nochmals die Grundidee :


Anfangsarray:

|Hans,Maria,Jochen,Hans,Maria,Johann,Hans,Rainer|

Quellelement ist immer das erste also prüfe Element1 mit allen anderen

Gefunden: Hans (Pos: 1,4,6)
Kopiere in gleich die Elemente1,4,6
Kopiere in ungleich Element 1

Lösche Elemente 1,4,6 (sind ja schon abgearbeitet)

bleibt also

|Maria,Jochen,Maria,Johann,Rainer|
Prüfe erstes wieder mit allen
Gefunden:Maria Pos 3
Kopiere Element 1,3 wieder in gleich
Kopiere in ungleich Element 1
Lösche wieder 1,3

bleibt also
Jochen , Johann , Rainer

etc.

Gruß
SkY
Ronnie
 2007-05-02 23:27
#76354 #76354
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my @folks = qw(Hans Maria Jochen Hans Maria Johann Hans Rainer);
my %seen;

for (0 .. $#folks) {
$seen{$folks[$_]}->{cnt}++;
push @{$seen{$folks[$_]}->{position}}, $_;
}

print Dumper \%seen;

my @unique = map { { $_ => $seen{$_} } } grep { $seen{$_}->{cnt} == 1 } keys %seen;
my @often = map { { $_ => $seen{$_} } } grep { $seen{$_}->{cnt} > 1 } keys %seen;

print Dumper \@unique, \@often;
PerlProfi
 2007-05-03 00:18
#76355 #76355
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Oder eine Lösung, die ganu das tut, was ich denke, dass du tun möchtest:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/usr/bin/perl
use strict;
use warnings 'all';
use Data::Dumper;

# NAME: sortieren()
# USE: Array nach dem angegebenen Algorithmus sortieren.
# PARAMETER: 1. Ausgangsarray
# 2. Gleich-Array
# 3. Ungleich-Array
# RETURNS: Koordinaten-Hash ( Referenz )
sub sortieren(\@\@\@)
{
# parameter holen
my($start, $gleich, $ungleich) = @_;
my $coords = {};

# ausgangsarray abarbeiten
while (@{$start})
{
# quellelement holen
my $quell = $start->[0];

# coordinaten array anlegen
my $co = $coords->{$quell} = [];

# nach gleichen elementen suchen
for my$j ($[..$#{$start})
{ push(@{$co}, $j) if $start->[$j] eq $quell }

# haben wir mehrere gleiche elemente?
if (@{$co} > 1)
{
# nach gleich kopieren
push(@{$gleich}, @{$start}[@{$co}]);
}

# quelle nach ungleich kopieren
push(@{$ungleich}, $quell);

# quellelement und duplikate aus dem start array loeschen
foreach my$ele (sort { $b <=> $a } @{$co})
{ splice(@{$start}, $ele, 1) }
}

# koordinaten der jeweiligen quellelemente zurueckgeben
return $coords;
} # sortieren

# Ausgangsarray initialisieren
my @arr = qw(Hans Maria Jochen Hans Maria Johann Hans Rainer);

# die beiden Arrays zum speichern der Werte definieren
my @gleich;
my @ungleich;

# sortieren
my $coords = sortieren(@arr, @gleich, @ungleich);

# ausgeben
print Dumper(\@arr, \@gleich, \@ungleich, $coords);

Ich denke die Vorgehensweise ist identisch mit deinem Algorithmus?

Du musst dir natürlich überlegen, ob du die Parameter wirklich so übergeben möchtest wie jetzt in dem Beispiel.
Es ist besser die Arrays als eindeutigere Referenzen zu übergeben, aber die Methode mit den \@ Prototypen wollte ich mal testen.

Wenn du die Übergabe ändern möchtest, musst du die \@ bei den Funktions-Prototypen durch drei $ ersetzen und unten beim Aufruf Referenzen an die Subroutine übergeben. In dem Biespiel also einfach einen \ vor die Arrays schieben.

MfG

edit: Die Stelle mit dem splice() an dem code nochmal aufgebessert, dank Ronnie\n\n

<!--EDIT|PerlProfi|1178189113-->
sKy
 2007-05-03 02:00
#76356 #76356
User since
2006-12-05
10 Artikel
BenutzerIn
[default_avatar]
@Ronnie leider ist dein Code für mich an einigen Stellen schwer nachzuvollziehen.

Ich habe es nochmals selbstversucht aber es scheint so nicht zu klappen obwohl es so doch idiotensicher gehen müsste:

Ich speicher immer die gefundenen Indizes speichere die Werte und lösche die Indizes bis das Array vollständig bearbeitet wurde:


Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
while(@satz)
{
my $quellelement=$satz[0]; #Erstes Element Satz nur für den späteren Vergleich nötig
my $quelldatei=$datei[0]; #jeweils erste Datei
push(@ungleich,$quelldatei);#Die Quelldatei wird in ungleich gespeichert

for my $pos($satz[1]..$#satz) #vom jeweils zweiten Element bis zum letzten
{
if ($quellelement eq $satz[$pos]) #Wenn erstes Element nochmals vorkommt
{
if ($counter==0) #Prüfe ob das Quellelement schon bearbeitet wurde
{
push(@gleich,$quelldatei); #Kopiere einmalig das jeweils erste Element in gleich
push(@Index,0); #Merk dir den Index
$counter++; #Zähler ist nun 1 somit wird die Schleife erstmal verlassen
}
push(@gleich,$datei[$pos]); #Speichere nun die anderen Werte in gleich
push(@Index,$pos); #und deren Position
}

}
$counter=0;
foreach my $element(@Index) #Löschen der nun schon verarbeiteter Indizes
{
splice @datei,$element,1;
splice @satz,$element,1;
}
@Index=(); #Neuinitialisierung von Index
}

system ("cp -v @gleich ./doppelt"); #Kopiere alle Dateien die identischen Inhalt haben
system("cp -v @ungleich ./einfach"); #Kopiere alle einfach vorkommenden Dateien


Danke bislang für eure Mühe!

Gruß
SkY
Ronnie
 2007-05-03 09:22
#76357 #76357
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Ohne mir den Code jetzt auf die Schnelle genauer betrachtet zu haben, aber wenn splice verwendet wird, veränderst du ja das Ursprungsarray. Damit verschieben sich i.A. auch die Indizes. Deshalb spliced man üblicherweise von hinten nach vorne.
PerlProfi
 2007-05-03 15:21
#76358 #76358
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Das splice() ist aber nicht das einzige was da nicht passt.

In deiner ersten for-Schleife ( for my $pos($satz[1]..$#satz) ) durchläufst du nicht das Array @satz vom 2. bis zum letzten Element.
Dort müsste eigentlich stehen: for my$pos (1..$#satz) oder for my$pos (1+$[..$#satz).

Die nächste if-Bedingung prüft dementsprechend auch nicht die richtigen Werte.

Welche Werte stehen in @satz und @datei ?
Du speicherst die Werte aus @datei wenn ein Wert in @satz mehrmals vorkommt, mit der jeweiligen Position in @satz.
Am Ende löschst du in beiden Arrays die Elemente an den Positionen wie sie in @satz vorkamen. ( Da ist ja noch der splice() Fehler )
Soll das so sein ?

Ausserdem verstehe ich nicht wieso du innerhalb der for-Schleife prüfst ob das quellelement schon bearbeitet wurde, durchlaufe doch einfach das gesamte Array @satz, dann kannst du den Kram mit $counter weglassen.

MfG
sKy
 2007-05-03 20:46
#76359 #76359
User since
2006-12-05
10 Artikel
BenutzerIn
[default_avatar]
Ich versuchs nochmal ich melde mich dann wieder...das mitm splice ist irgendwie komisch...

Gruß
SkY
<< |< 1 2 >| >> 17 Einträge, 2 Seiten



View all threads created 2007-05-01 22:55.