Sie sind auf Seite 1von 5

Informatik I - Pr ufung 2012

Losung
28. Mai 2014
1 Variablen, Zeiger und Kontrollstrukturen
1.1
Fehler erkannt : 0.5 Pkt
Fehler verbessert : 0.5 Pkt
i nt main ( )
{
i nt i = 0;
i nt j = 0;
f l o a t array [ 1 0 ] ;
f o r ( ; i < 10; i++, j++) //Komma!
{
array [ i ] = j ;
}
f o r ( i nt l=1; l < 9; l++) // l de f i ni e r e n !
{
array [ l ] = ( 0. 5 ( array [ l+1] ) ) ; // f e hl e nde Klammer
}
f o r ( j = 0; j < 10; j++)
{
i f ( j < 5 . )
array [ j ] = array [ j +5] ; // f a l s c he Zuweisung
cout << array [ j ] << endl ;
}
r et ur n 0; // i nt zurueckgeben
}
1.2
je 2 Pkt
fn1 : 8, fn2 : 5, fn3 : 0, fn4 : 6, fn5 : 4
1.3 je 1 Pkt
a == 1 | | a == 2
a == 1 | | a == 2 | | a == 5 | | a == 6
a == 9
a != 1 && a != 2 && a != 5 && a != 6 && a != 9
1.4 1 Pkt
f o r ( i nt i = 0; str [ i ] != ' \0 ' ; i++)
2 Klassen und Zugriskontrolle
2.1
Scope : Der Sichtbarkeitsbereich von Variablen, Methoden, etc. (1 Pkt f ur Sichtbarkeitsbereich)
Zugriskontrolle : Mittels public, protected und private wird festgelegt, von wo ein Element
zugreifbar ist. (1 Pkt f ur public, private)
Destruktor : Eine Methode die automatisch aufgerufen wird bevor die Lebensspanne eines Ob-
jektes auslauft. In dieser Methode konnen Aufraumarbeiten erledigt werden. (0.5 Pkt f ur
automatischer Aufruf. 0.5 Pkt f ur Aufraumen)
2.2 je 0.5 Pkt
Zugri myDefault myPublic myPrivate
Mitglieder der selben Klasse Ja Ja Ja
Keine Mitglieder Nein Ja Nein
1
2.3
Klassen Deklaration und ; : 1 Pkt
Konstruktor, Destruktor : 1 Pkt
private : 1 Pkt
Variablen Deklaration : 1 Pkt
c l a s s Exam
{
publ i c :
Exam ( ) ; // Standardkonstruktor
Exam ( ) ; // St andar ddes t r ukt or
pr i vat e :
char name ;
i nt p1 , p2 , p3 , p4 ;
};
2.4
Methoden Deklaration im header : 1 Pkt
Exam:: : 1 Pkt
this Pointer : 1 Pkt
Korrekte Initialisierung ( >) : 1 Pkt
//im header :
publ i c :
Exam ( i nt p1 , i nt p2 , i nt p3 , i nt p4 , char name ) ;
//im body :
Exam : : Exam ( i nt p1 , i nt p2 , i nt p3 , i nt p4 , char name )
{
t hi s >p1 = p1 ; //Achtung : t hi s benutzen
t hi s >p2 = p2 ;
t hi s >p3 = p3 ;
t hi s >p4 = p4 ;
t hi s >name = name ;
}
Bem.: Hier tragen im Konstruktor die Argumente die gleichen Namen wie die Mitgliedsvaria-
blen. Dies geht nur, wenn man den this Pointer benutzt! (sonst p1=p1;...)
2.5
Methoden Deklaration im header : 1 Pkt
Exam:: : 0.5 Pkt return Wert : 1 Pkt
// im header :
publ i c :
i nt computeTotal ( ) ;
// im cpp :
i nt Exam : : computeTotal ( )
{
r et ur n ( p1 + p2 + p3 + p4 ) ;
}
2.6
2 Objekte : 1 Pkt
int main... return 0; : 1 Pkt
cout, Aufruf : 1 Pkt
i nt main
{
Exam studentA ( 1 , 2 , 3 , 4 , Adam ) ;
Exam studentB ( 4 , 3 , 2 , 1 , Eva ) ;
cout << studentA : << studentA . computeTotal ( ) << endl ;
cout << studentB : << studentB . computeTotal ( ) << endl ;
r et ur n 0;
}
3 Listen und Baume
3.1
pro korrektes Richtig/Falsch : 1 Pkt
pro korrekte Erklarung : 1 Pkt
Wenn die Anzahl der zu speichernden Elemente im Voraus nicht bekannt ist, dann ist es besser
einen Vektor (array) zu verwenden.
Falsch. Um die Grosse des Vektors zu andern m ussen wir Speicher neu zuweisen und alle
Daten kopieren. Bei den Listen konnen wir einfach einen Knoten hinzuf ugen.
Die Suche in einem sortierten Vektor (array) kann schneller ausgef uhrt werden als in einer
sortierten Liste.
Richtig. Vektoren erlauben sofortigen Zugri auf jedes Element. Bei den Listen m ussen
wir ganze Teilbaume der Reihe nach durchsuchen.
F ur die selbe Anzahl Elemente benotigen Listen mehr Speicherplatz als Vektoren.
Richtig. Listen brauchen f ur jedes Element noch einen Pointer.
Das Loschen eines Elementes benotigt weniger Operationen unter Verwendung eines Vektors.
Falsch. Beim Loschen eines Elements im array m ussen wir alle anderen Elemente eine Position
nach hinten verschieben.
3.2
korrekter Vorteil : 2 Pkt
korrekter Nachteil : 2 Pkt
2 korrekte Beispiele : 4 Pkt
Doubly linked lists erlauben es, die Liste sowohl vorwarts als auch r uckwarts zu durchlaufen.
Dies ermoglicht es zum Beispiel, einen Knoten vor einen gegebenen Knoten einzusetzen, ohne
daf ur die ganze Liste durchlaufen zu m ussen um den gegebenen Knoten zu nden. Allerdings ist
2
die Implementierung m uhsamer und sie verbrauchen mehr Speicherplatz. Das Einsetzen eines
Knotens am Anfang der Liste w urde weniger Operationen bei einer einfachen Liste benotigen.
3.3
pro Zeile : 1 Pkt
; am Ende : 1 Pkt
s t r uc t binTreeNode{
i nt value ;
binTreeNode left , right ;
};
3.4
Abbruchbedingung : 1 Pkt
korrekte restliche Losung : 4 Pkt
voi d printBinSearchTree ( binTreeNode root )
{
i f ( root == NULL )
r et ur n ;
printBinSearchTree ( root>left ) ;
cout << root>value << endl ;
printBinSearchTree ( root>right ) ;
}
// oder :
voi d printBinSearchTree ( binTreeNode root )
{
i f ( root != NULL )
{
printBinSearchTree ( root>left ) ;
cout << root>value << endl ;
printBinSearchTree ( root>right ) ;
}
}
3.5
Abbruchbedingung : 2 Pkt
Rekursion links : 2 Pkt
Rekursion rechts : 2 Pkt
binTreeNode findBinSearchTree ( binTreeNode root , i nt value )
{
i f ( root == NULL )
r et ur n NULL ;
i f ( root>value == value )
r et ur n root ;
i f ( value < root>value )
r et ur n findBinSearchTree ( root>left , value ) ;
e l s e
r et ur n findBinSearchTree ( root>right , value ) ;
}
3.6
korrektes Durchlaufen : 4 Pkt
neuen Knoten zuweisen : 1 Pkt
Nachfolgerknoten NULL zuweisen : 2 Pkt
neuen Knoten korrekt verbinden : 1 Pkt
voi d insertBinSearchTree ( binTreeNode root , i nt value )
{
i f ( value < root>value )
{
i f ( root>left != NULL ) // kei n Bl attknoten
insert ( root>left , value ) ;
e l s e // Bl attknoten e r r e i c ht
{
binTreeNode newNode = new binTreeNode ;
newNode>left = NULL ;
newNode>right = NULL ;
newNode>value = value ;
root>left = newNode ;
}
}
e l s e
{
i f ( root>right != NULL )
insert ( root>right , value ) ;
e l s e
{
binTreeNode newNode = new binTreeNode ;
newNode>left = NULL ;
newNode>right = NULL ;
newNode>value = value ;
root>right = newNode ;
}
3
}
}
oder :
voi d insertBinSearchTree ( binTreeNode root , i nt value )
{
binTreeNode curr = root ;
binTreeNode next = root ;
whi l e ( next != NULL )
{
i f ( curr>value > value )
next = curr>left ;
e l s e
next = curr>right ;
}
next = new binTreeNode ;
i f ( next == NULL )
{
cout << memory a l l o c a t i o n e r r or << endl ;
r et ur n ;
}
next>left = NULL ;
next>right = NULL :
next>value = value :
i f ( curr>value > value )
curr>left = next ;
e l s e
curr>right = next ;
}
4 Das Rucksackproblem
4.1
tmp : 1 Pkt
korrektes Vertauschen : 1 Pkt
korrektes Benutzen der Pointers (*) : 2 Pkt
voi d swap ( Gegenstand a , Gegenstand b )
{
Gegenstand tmp = a ;
a = b ;
b = tmp ;
}
4.2 maxWert : 2 Pkt
for Schleife : 2 Pkt
if Bedingung : 1 Pkt
if Block : 2 Pkt
return : 1 Pkt
i nt getIndexOfMax ( i nt l , i nt r , Gegenstand gegenstaende )
{
i nt maxIndex = l ;
doubl e maxWert = doubl e ( gegenstaende [ l ] . wert ) /gegenstaende [ l ] .
gewicht ;
f o r ( i nt i = l + 1; i < r ; i++)
{
i f ( doubl e ( gegenstaende [ i ] . wert ) /gegenstaende [ i ] . gewicht >
maxWert )
{
maxIndex = i ;
maxWert = doubl e ( gegenstaende [ i ] . wert ) /gegenstaende [ i
] . gewicht ;
}
}
r et ur n maxIndex ;
}
4.3 for Schleife : 1 Pkt
getIndexOfMax Aufruf : 2 Pkt
swap Aufruf : 2 Pkt
voi d selectionSort ( Gegenstand gegenstaende , i nt n )
{
f o r ( i nt i = 0; i < n ; i++)
{
i nt maxIndex = getIndexOfMax ( i , n , gegenstaende ) ;
swap(&gegenstaende [ i ] , &gegenstaende [ maxIndex ] ) ;
}
}
4
4.4
wert, gewicht initialisieren : 1 Pkt
selectionSort Aufruf : 2 Pkt
for Schleife : 1 Pkt
if Bedingung, Block : 3 Pkt
Summen : 2 Pkt
return : 1 Pkt
i nt greedyRucksack ( Gegenstand gegenstaende , i nt n , i nt m )
{
i nt wert = 0;
i nt gewicht = 0;
selectionSort ( gegenstaende , n ) ;
f o r ( i nt i = 0; i < n ; i++)
{
i f ( gewicht + gegenstaende [ i ] . gewicht <= m )
{
wert = wert + gegenstaende [ i ] . wert ;
gewicht = gewicht + gegenstaende [ i ] . gewicht ;
}
}
r et ur n wert ;
}
4.5
Nein : 1 Pkt
Begr undung : 2 Pkt
Nein. Wir packen immer nur den Gegenstand, der zum zum Zeitpunkt der Wahl den grossten
Gewinn verspricht. Im Endeekt kann es aber sein, dass wir ein besseres Resultat erzielen wenn
wir Gegenstande einpacken, die zwar einzeln gesehen einen kleineren Gewinn haben, aber zu-
sammen ein grosseres Resultat ergeben. Ein optimales Resultat erzielt man durch rekursives,
kombinatorisches Vorgehen (dynamisches Programmieren).
5