Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]814[/thread]

Kleine Anfänger Frage

Leser: 2


<< >> 6 Einträge, 1 Seite
dergutajanek
 2006-09-20 20:05
#8692 #8692
User since
2006-09-20
1 Artikel
BenutzerIn
[default_avatar]
Hallo zusammen,

ich als Programmieranfänger habe ein kleines Problem:

ich möchte eine Tabelle darstellen, dessen Zellen mit folgendem gefüllt werden sollen. ich habe ein eine art code mit buchstaben (abcde) dabei sollen alle möglichkeiten dargestellt werden wie dieser code sein kann. die buchstaben sollen klein und groß geschrieben werden. Also: Abcde, aBcde, abCde,... ABCDE.

Wie kann ich das automatisierren?

Die Darstellung in der Tabelle ist kein Problem, eher die funktionen die alle Möglichkeiten ermittelt.

Gruß Janek
topeg
 2006-09-20 23:11
#8693 #8693
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Hier hast du mal zwei Möglichkeiten, wie man es Programmieren könnte in einem Script. Eine kurze Erklärung ist auch enthalten.
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
#!/usr/bin/perl
use strict;

my @elemente=@ARGV;
die "$0 element_a element_b [[[element_d] element_c] ...]\n" if(@elemente<=1);

print "Elemente: ".join('; ', @elemente)."\n";
my @liste=();

print "Variantionen A:\n";
@liste=&variants_a(@elemente);
for my $ele (@liste)
{ print " ".join('; ',@{$ele})."\n"; }

print "Variantionen B:\n";
@liste=&variants_b(@elemente);
for my $ele (@liste)
{ print " ".join('; ',@{$ele})."\n"; }

# Rekursiv Programmiert
# Die Funktion ruft sich selber auf,
# solange im Array noch Elemnte enthalten sind.
# Zurückgeben wird immer ein Array mit anonymen Arrays darin.
#
# zu bemerken ist, daß die vollständige Liste
# aller Variationen erst zur verfügung steht,
# wenn die funktion vollstzändig durchgelaufen ist.
# Dafür aber ist sie sehr schnell, verbraucht aber auch recht viel Speicher
sub variants_a(@)
{
my (@arr) = @_;
# erstes Element entfernen
my $first=shift(@arr);
# wenn kein Element mehr in der Liste ist,
# dann gib ein Array mit zwei anonymen Arrays zurück,
# welche jeweils ein Element, groß und kleingeschrieben enhalten
return ([lc($first)],[uc($first)]) unless(@arr>0);
# sind noch Elemnte enthalten, so rufe die Funktion nochmal auf
# und übergebe das restliche Array
# gehe die gesammte Rückkabe durch und ersetze jedes anonyme Array durch zwei neue,
# vor die jeweils das alte anonyme Array enthalten,
# plus der Groß/Kleinschreibvariante es entfernten Elementes
return map { ( [lc($first),@{$_}], [uc($first),@{$_}] ) } variants_a(@arr);
}

# Als binärer Zähler Programmiert
# jedes Element wird als "Bit" aufgefasst,
# welches Zwei zusände annehmen kann.
# Entweder wird es groß geschrieben (1),
# oder klein geschrieben (0).
# dann wird Hochgezählt.
# Ein Beispiel an 3 Elemneten
# 0;0;0
# 1;0;0
# 0;1;0
# 1;1;0
# 0;0;1
# 1;0;1
# 0;1;1
# 1;1;1
#
# Hier steht zu jedem Zeitpunkt
# eine vollständige Liste aller Elemnte
# und deren aktuelle Zustände zur verfügung.
# Die Funktion ist Speichersparend,
# aber auch recht langsam
sub variants_b(@)
{
my (@arr) = @_;
my @ret=();
# erstmal alles kleinschreiben
# (alle Bits auf 0)
for my $i (@arr){ $i=lc($i); }
my $lang=@arr;
my $i=1;
# solange nicht das gesammte Array durchlaufen wurde
# weiter machen
while($i<$lang)
{
# Jedes Element im array anstringen
for($i=0; $i<$lang; $i++)
{
# ist ein Element klein geschrieben? (0)
if(lc($arr[$i]) eq $arr[$i])
{
# Element groß schreiben (1)
$arr[$i]=uc($arr[$i]);
# for-schleife abbrechen
last;
}
# Element klein schreiben (0)
$arr[$i]=lc($arr[$i]);
}
# Aktuellen Zustand des Array kopieren und als anonymes Array speichern
push(@ret,[@arr]);
}
return @ret;
}
docsnyder
 2006-09-21 19:02
#8694 #8694
User since
2005-09-08
300 Artikel
BenutzerIn
[Homepage] [default_avatar]
Es geht auch kürzer:

Code: (dl )
1
2
3
4
5
6
7
8
9
sub modify {
my ($str) = @_;

my ($head, $tail) = ( substr($str, 0, 1), substr($str, 1, length($str)-1) );

return length($tail) ? map { (lc($head) . $_, uc($head) . $_) } modify($tail) : $head;
}

printf("$_\n") foreach ( modify('abcdef') );


Gruß, Doc\n\n

<!--EDIT|docsnyder|1158850949-->
topeg
 2006-09-22 00:45
#8695 #8695
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Jedoch hatt er dann keine Arrays mehr, die er auslesen kann um daraus eine Tabelle (HTML schätze ich mal) zu machen. Sicher er kann es splitten doch warum erst zusammenfügen und dann wieder spliten. Auch die rekusive Variante von mir kann man kürzer schreiben, jedoch fand ich es nicht sinnvoll, da dann etwas an lesbarkeit und dokumentierbarkeit verloren gegangen wäre.
Aber hier mal die minimalistische Variante meinerseits:
Code: (dl )
1
2
3
4
sub variants {
my $e=shift(@_);
return @_ ? map { ( [lc($e),@{$_}], [uc($e),@{$_}] ) } variants(@_) : ([lc($e)],[uc($e)]);
}

kürzer gehts wohl nicht :-)\n\n

<!--EDIT|topeg|1158871637-->
docsnyder
 2006-09-22 01:52
#8696 #8696
User since
2005-09-08
300 Artikel
BenutzerIn
[Homepage] [default_avatar]
Gratuliere topeg, Du hast mich getoppt!

Aber auch bei mir war es nicht meine eigene Idee: der Algorithmus war geklaut, und war im Forum, ich glaube, unter dem Suchbegriff "permutation" (von esskar) zu lesen.

Gratuliere! Ich lerne von Leuten wie Dir!

Gruß, Doc
topeg
 2006-09-22 07:35
#8697 #8697
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Daher habe ich es ja auch, mehr oder weniger. (zumindest wußte ich nicht, daß man ein Array dadurch vergrößern kann, indem man innerhalb von "map" (oder auch "for") Arrayelement durch einen Array ersetzt)

Wie mein Großvater sagte: "Das Wissen fällt einem vor die Füße, man darf nur keinen steifen Rücken haben." :-)
<< >> 6 Einträge, 1 Seite



View all threads created 2006-09-20 20:05.