Thread Kombinationen und ihre Umkehrung (7 answers)
Opened by Linuxer at 2006-09-29 03:00

topeg
 2006-09-30 00:56
#70396 #70396
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Ich habe mich mal was programmiert, das deinen Vorstellungen wohl recht nahe kommt. Etwas Dokumentiert ist es auch. :-)
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#!/usr/bin/perl
use strict;
use warnings;

######################################################
# Funktionen #
##############

# Liste einlesen
# Werte:
# > Name des ersten Eintrages
# > Name des zweiten Eintrages
# > Name des dritten Eintrages
# > Filehandle
# < gelesenen Liste
sub parse_liste($$$$)
{
my ($erst,$dann,$letzt,$fh)=@_;
my @liste=();

while(my $l=<$fh>)
{ push(@liste,{$erst=>[$1], $dann=>[$2], $letzt=>[$3]}) if($l=~/^([^\s]+)\s+(\d+)\s+([^\s]+)$/); }

return @liste;
}

# Einträge zusammenfassen
# Werte:
# > die Hashrefferenz
# > Name des Wertes, dessen Ihnalt zusammengefst werden soll
# < String, der die vereinte liste enthält.
sub myjoin($$)
{
my ($ref,$name)=@_;
# ich benutze hier den "Nullsring" als Trenner,
# da er normalerweise niemals in einem String vorkommt
return join("\000", @{$ref->{$name}});
}

# Werte vergelichen (als Aufruf aus "sort" heraus)
# Werte:
# > erste Hashreferenz
# > zweite Hashreferenz
# > Name des primären Sortierwertes
# > Name des sekundären Sortierwertes
# > Name des terziären Sortierwertes
sub vergleiche($$$$$)
{
my ($wa,$wb,$erst,$dann,$letzt)=@_;
if( myjoin($wa,$erst) eq myjoin($wb,$erst) )
{
return myjoin($wa,$letzt) cmp myjoin($wb,$letzt) if( myjoin($wa,$dann) eq myjoin($wb,$dann) );
return myjoin($wa,$dann) cmp myjoin($wb,$dann);
}
return myjoin($wa,$erst) cmp myjoin($wb,$erst);
}

# Liteneinträge zusammenfassen
# Werte:
# > Name des ersten Wertes der übereinstimmen muss
# > Name des zweiten Wertes der übereinstimmen muss
# > Name des Wertes der bei positiver Prüfung zusammengefasst wird
# < zusammengefasste Liste
sub komibiere($$$@)
{
my ($erst,$dann,$letzt,@liste)=@_;

# erstmal sortieren
@liste=sort{ vergleiche($a,$b,$erst,$dann,$letzt) }@liste;

# ein Eintrag kommt immer in die Ausgabeliste
my @liste_k=({ $erst => $liste[0]->{$erst}, $dann => $liste[0]->{$dann}, $letzt => $liste[0]->{$letzt} });
shift(@liste);

# Die Eingabeliste durcharbeiten
while(@liste)
{
my $eintrag=shift(@liste);
if(
myjoin($eintrag,$erst) eq myjoin($liste_k[-1],$erst) &&
myjoin($eintrag,$dann) eq myjoin($liste_k[-1],$dann)
)
{ push(@{$liste_k[-1]->{$letzt}},@{$eintrag->{$letzt}}); }
else
{ push(@liste_k,{ $erst=>$eintrag->{$erst}, $dann=>$eintrag->{$dann}, $letzt=>$eintrag->{$letzt} }); }
}
return @liste_k;
}

# Listeneinträge ausgeben
# Werte:
# > Name des ersten Eintrages
# > Name des zweiten Eintrages
# > Name des dritten Eintrages
sub my_print($$$@)
{
my ($erst,$dann,$letzt,@l)=@_;
print '/','#'x32,"\\\n";
printf("|%10s|%10s|%10s|\n",$erst,$dann,$letzt);
print '+','-'x10,'+','-'x10,'+','-'x10,"+\n";
for my $i (@l)
{
my $e= join(',',@{$i->{$erst}});
my $d= join(',',@{$i->{$dann}});
my $l= join(',',@{$i->{$letzt}});
printf("|%10s|%10s|%10s|\n",$e,$d,$l);
}
print '\\','#'x32,"/\n";
}

######################################################
# Programm #
############

my @l=parse_liste('quelle','port','ziel',*DATA);

print "Rohdaten\n";
my_print('quelle','port','ziel',@l);

print "\"Ports\" zusammengefasst\n";
@l=komibiere('quelle','ziel','port',@l);
my_print('quelle','port','ziel',@l);

print "\"Quellen\" zusammengefasst\n";
@l=komibiere('ziel','port','quelle',@l);
my_print('quelle','port','ziel',@l);

print "\"Ziele\" zusammengefasst\n";
@l=komibiere('quelle','port','ziel',@l);
my_print('quelle','port','ziel',@l);

exit(0);

######################################################
# DATAZEILEN #
##############
__DATA__
A 1 b
A 2 b
K 24 c
P 2 d
B 3 b
B 1 b
B 22 a
K 2 d
P 1 a
P 1 b
K 1 c
K 2 a
K 4 a
C 22 c
C 4 a
K 22 a
B 11 c
D 2 e
D 1 a
A 33 c
W 1 q
L 3 w
Z 11 q
W 11 q
Z 1 q
D 1 c
P 1 c


edit: Fehler behoben...\n\n

<!--EDIT|topeg|1159564090-->

View full thread Kombinationen und ihre Umkehrung