Download as pdf or txt
Download as pdf or txt
You are on page 1of 36

ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»

ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

ΑΚΑΔΗΜΑΙΚΟ – ΕΤΟΣ 2020-2021


2η ΕΞΕΤΑΣΤΙΚΗ
ΕΝΔΕΙΚΤΙΚΕΣ ΑΠΑΝΤΗΣΕΙΣ
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

Περιεχόμενα
1. ΕΝΔΕΙΚΤΙΚΕΣ ΑΠΑΝΤΗΣΕΙΣ ΘΕΜΑΤΩΝ ΜΕΤΑΓΛΩΤΤΙΣΤΩΝ ........................................................... 3
1.1 1η Άσκηση μεταγλωττιστές................................................................................................... 3
1.2 2η Άσκηση μεταγλωττιστές ................................................................................................... 6
1.3 3η Άσκηση μεταγλωττιστές ................................................................................................... 9
2. ΕΝΔΕΙΚΤΙΚΕΣ ΑΠΑΝΤΗΣΕΙΣ ΘΕΜΑΤΩΝ UML ............................................................................... 12
2.1 1η Άσκηση UML ................................................................................................................... 12
2.2 2η Άσκηση UML ................................................................................................................... 15
2.3 3η Άσκηση UML ................................................................................................................... 18
3. ΕΝΔΕΙΚΤΙΚΕΣ ΑΠΑΝΤΗΣΕΙΣ JAVA ................................................................................................. 22
3.1 1η Άσκηση Java .................................................................................................................... 22
3.2 2η Άσκηση Java .................................................................................................................... 26
3.3 3η Άσκηση Java .................................................................................................................... 29
4.1 4η Άσκηση Java .................................................................................................................... 33
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

1. ΕΝΔΕΙΚΤΙΚΕΣ ΑΠΑΝΤΗΣΕΙΣ ΘΕΜΑΤΩΝ ΜΕΤΑΓΛΩΤΤΙΣΤΩΝ

1.1 1η Άσκηση μεταγλωττιστές


Δίνεται η παρακάτω γραμματική:

(compilers_essay.1a.q)
Ως αρχικό σύμβολο θεωρήστε το σύμβολο S. Τα τερματικά σύμβολα της γραμματικής είναι τα (
) x y z + και -.

Ερώτημα 1: Να συμπληρώσετε έναν πίνακα σαν τον παρακάτω για τα σύνολα First και Follow των
μη-τερματικών συμβόλων της γραμματικής. Στην απάντησή σας πρέπει, επίσης, να φαίνονται ανα-
λυτικά τα βήματα που κάνατε για να καταλήξετε στα σύνολα αυτά.

(compilers_essay.1b.q)

Ερώτημα 2: Να υπολογίσετε τον πίνακα ανίχνευσης του μοντέλου LL(1) ανίχνευσης για την γραμ-
ματική τεκμηριώνοντας τις επιλογές σας. Να αξιοποιήσετε την αρίθμηση των κανόνων της γραμ-
ματικής για τη συμπλήρωση του πίνακα.
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

Απάντηση
Ερώτημα 1
ΣΥΝΟΛΑ First
Για τον υπολογισμό των συνόλων First χρησιμοποιούμε τον αλγόριθμο:
Διακρίνουμε τις εξής περιπτώσεις για την προτασιακή μορφή :
1.εάν  είναι ένα γραμματικό σύμβολο ή , τότε
εάν  είναι ένα τερματικό a, τότε First() = First(a) = {a}
εάν  είναι το , τότε First() = First() = {}

εάν  είναι ένα μη-τερματικό Χ και Χ → β1 | β2 | … | βκ, τότε First() =


First(X) = First(β1)  First(β2)  …  First(βκ)
2.εάν  είναι μια συμβολοσειρά γραμματικών συμβόλων  = Χ1Χ2…ΧΝ, τότε
First()={}; j=0;
REPEAT
j=j+1;
Προσθέτουμε στο First() το First(Xj) – {}
UNTIL Xj δεν είναι απαλείψιμο (δεν παράγει το ) ή j=N
Εάν Χ1Χ2…ΧΝ, είναι απαλείψιμη, τότε προσθέτουμε το  στο First()
first(S) = first((SA)) + first(x) = { ( } + { x } = { (, x } (1),(2)
first(A) = first(ε) + first(+SB) + first(By) = { ε } + { + } + { y, - } = { +, -
, y, ε } (3),(4),(5),(6),(7)
first(B) = first(ε) + first(-SAz) = { ε } + { - } = { -, ε } (6),(7)

ΣΥΝΟΛΑ Follow
Για τον υπολογισμό των συνόλων Follow χρησιμοποιούμε τον αλγόριθμο:
Έστω G=(S, N, T, P), A  N και $ το τέλος μιας συμβολοσειράς
1. εάν Α = S, τότε $  Follow(Α)
2.  p  P, και Α περιλαμβάνεται στο δεξί μέρος του p με τη μορφή:
Β → γΑδ
i. εάν δ αρχίζει από τερματικό σύμβολο c, τότε c  Follow(Α)
ii. εάν δ αρχίζει από μη-τερματικό σύμβολο, τότε προσθέτουμε το First(δ) –
{}
iii. εάν δ= ή δ * , τότε προσθέτουμε το Follow(B)

Το S είναι αρχικό σύμβολο της γραμματικής, άρα $  Follow(S).


Το S εμφανίζεται στο δεξί μέλος των κανόνων (1), (4) και (7) ακολουθούμενο από ένα μη-
τερματικό σύμβολο, άρα αντίστοιχα έχουμε:
First(A)) – {ε} = { +, -, y, ) }  Follow(S)
First(Β) – {ε} = { - }  Follow(S) και
First(Az) – {ε} = { +, -, y, z }  Follow(S)
Επιπλέον επειδή το Β είναι απαλείψιμο από τον κανόνα (4) προκύπτει
ότι Follow(A)  Follow(S).
Άρα:
Follow(S) = { $, +, -, y, ), z } + Follow(A)

Το Α εμφανίζεται στο δεξί μέλος των κανόνων (1) και (7) ακολουθούμενο από ένα τερματικό
σύμβολο, άρα:
Follow(A) = {)} + {z} = { ), z }

Το B εμφανίζεται στο δεξί μέλος των κανόνων (4) και (5) ακολουθούμενο από
ε (άρα Follow(A)  Follow(Β)) και ένα τερματικό σύμβολο, αντίστοιχα:
Follow(Β) = Follow(A) + {y} = { ), z, y }

Έτσι, έχουμε:
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

First Follow
S x( +-)yz$
A +-yε )z
B -ε )yz

Ερώτημα 2

Ο πίνακας ανίχνευσης ορίζεται εφαρμόζοντας τον παρακάτω αλγόριθμο:


• Για όλους τους κανόνες Aàa, εκτελούνται τα ακόλουθα βήματα:
1. για κάθε τερματικό σύμβολο b, όπου b Î First(a), προσθέτουμε τον κανόνα Aàa στη
θέση Μ[A, b]
2. εάν e Î First(a), τότε προσθέτουμε τον κανόνα Aàa στη θέση M[A, c] για κάθε τερ-
ματικό σύμβολο c που περιέχεται στο σύνολο Follow(A), επίσης προσθέτουμε τον κα-
νόνα Aàa στη θέση M[A, $], εάν $ Î Follow(A)
• Τα στοιχεία του ΠΑ που δεν έχουν οριστεί με τα βήματα 1 και 2 θα έχουν τιμή error

(1) S à ( S A )
Ισχύει ότι First(( S A )) = { ( } , άρα προσθέτουμε τον κανόνα (1) στη θέση Μ[S, (] του πίνακα.
(2) S à x
Ισχύει ότι First(x) = { x } , άρα προσθέτουμε τον κανόνα (2) στη θέση Μ[S, x] του πίνακα.
(3) A à ε
Ισχύει ότι First(ε) = { ε }, οπότε χρησιμοποιούμε το σύνολο Follow(A) και προσθέτουμε τον κανόνα
(3) στις θέσεις Μ[Α, z] και Μ[Α, )] του πίνακα.
(4) Α à + S B
Ισχύει ότι First(+ S B) = { + } , άρα προσθέτουμε τον κανόνα (4) στη θέση Μ[A, +] του πίνακα.
(5) Α à B y
Ισχύει ότι First(B y) = { -, y } , άρα προσθέτουμε τον κανόνα (5) στις θέσεις Μ[Α, -] και Μ[Α, y] του
πίνακα.
(6) B à ε
Ισχύει ότι First(ε) = { ε }, οπότε χρησιμοποιούμε το σύνολο Follow(Β) και προσθέτουμε τον κανόνα
(6) στις θέσεις Μ[Β, y], Μ[B, z] και Μ[B, )] του πίνακα.
(7) B à - S A z
Ισχύει ότι First(- S A z) = { - } , άρα προσθέτουμε τον κανόνα (7) στη θέση Μ[B, -] του πίνακα.

Έτσι, έχουμε:

x y z + - ( ) $
S 2 - - - - 1 - -
A - 5 3 4 5 - 3 -
B - 6 6 - 7 - 6 -
Page Break
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

1.2 2η Άσκηση μεταγλωττιστές


Δίνεται η παρακάτω γραμματική:

(compilers_essay.2a.q)
Ως αρχικό σύμβολο θεωρήστε το σύμβολο F. Τα τερματικά σύμβολα της γραμματικής είναι τα id *
( ) και ,.
Ερώτημα 1: Να συμπληρώσετε έναν πίνακα σαν τον παρακάτω για τα σύνολα First και Follow των
μη-τερματικών συμβόλων της γραμματικής. Στην απάντησή σας πρέπει, επίσης, να φαίνονται ανα-
λυτικά τα βήματα που κάνατε για να καταλήξετε στα σύνολα αυτά.

(compilers_essay.2b.q)
Ερώτημα 2: Να υπολογίσετε τον πίνακα ανίχνευσης του μοντέλου LL(1) ανίχνευσης για την γραμ-
ματική. Να αξιοποιήσετε την αρίθμηση των κανόνων της γραμματικής για τη συμπλήρωση του πί-
νακα.
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

Απάντηση
Ερώτημα 1
ΣΥΝΟΛΑ First
Για τον υπολογισμό των συνόλων First χρησιμοποιούμε τον αλγόριθμο:
Διακρίνουμε τις εξής περιπτώσεις για την προτασιακή μορφή :
1.εάν  είναι ένα γραμματικό σύμβολο ή , τότε
εάν  είναι ένα τερματικό a, τότε First() = First(a) = {a}
εάν  είναι το , τότε First() = First() = {}

εάν  είναι ένα μη-τερματικό Χ και Χ → β1 | β2 | … | βκ, τότε First() =


First(X) = First(β1)  First(β2)  …  First(βκ)
2.εάν  είναι μια συμβολοσειρά γραμματικών συμβόλων  = Χ1Χ2…ΧΝ, τότε
First()={}; j=0;
REPEAT
j=j+1;
Προσθέτουμε στο First() το First(Xj) – {}
UNTIL Xj δεν είναι απαλείψιμο (δεν παράγει το ) ή j=N
Εάν Χ1Χ2…ΧΝ, είναι απαλείψιμη, τότε προσθέτουμε το  στο First()
first(F) = first(T id (A)) = first(id X) = { id } (1),(2)
first(T) = first(id X) = { id } (2)
first(X) = first(*X) + first(ε) = { * } + { ε } = { *, ε } (3),(4)
first(A) = first(T id Z) + first(ε) = { id, ε } (2),(5),(6)
first(Z) = first(, T id Z) + first(ε) = { ,, ε } (7),(8)

ΣΥΝΟΛΑ Follow
Για τον υπολογισμό των συνόλων Follow χρησιμοποιούμε τον αλγόριθμο:
Έστω G=(S, N, T, P), A  N και $ το τέλος μιας συμβολοσειράς
1. εάν Α = S, τότε $  Follow(Α)
2.  p  P, και Α περιλαμβάνεται στο δεξί μέρος του p με τη μορφή:
Β → γΑδ
i. εάν δ αρχίζει από τερματικό σύμβολο c, τότε c  Follow(Α)
ii. εάν δ αρχίζει από μη-τερματικό σύμβολο, τότε προσθέτουμε το First(δ) –
{}
iii. εάν δ= ή δ * , τότε προσθέτουμε το Follow(B)

Το F είναι αρχικό σύμβολο της γραμματικής, άρα $  Follow(F).


Το F δεν εμφανίζεται στο δεξί μέλος κανενός κανόνα.
Follow(F) = { $ }

Το T εμφανίζεται στο δεξί μέλος των κανόνων (1), (5) και (7) ακολουθούμενο από ένα τερ-
ματικό σύμβολο, άρα:
Follow(T) = {id}

Το X εμφανίζεται στο δεξί μέλος των κανόνων (2) και (3) ακολουθούμενο από ε:
Follow(X) = Follow(T) = { id }

Το A εμφανίζεται στο δεξί μέλος του κανόνα (1) ακολουθούμενο από τερματικό σύμβολο:
Follow(Α) = { ) }

Το Ζ εμφανίζεται στο δεξί μέλος των κανόνων (5) και (7) ακολουθούμενο από ε:
Follow(Ζ) = Follow(Α) = { ) }
Έτσι, έχουμε:
First Follow
F id $
T id id
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

X ε * id
A ε id )
Z ε , )

Ερώτημα 2

Ο πίνακας ανίχνευσης ορίζεται εφαρμόζοντας τον παρακάτω αλγόριθμο:


• Για όλους τους κανόνες Aàa, εκτελούνται τα ακόλουθα βήματα:
1. για κάθε τερματικό σύμβολο b, όπου b Î First(a), προσθέτουμε τον κανόνα Aàa στη
θέση Μ[A, b]
2. εάν e Î First(a), τότε προσθέτουμε τον κανόνα Aàa στη θέση M[A, c] για κάθε τερ-
ματικό σύμβολο c που περιέχεται στο σύνολο Follow(A), επίσης προσθέτουμε τον κα-
νόνα Aàa στη θέση M[A, $], εάν $ Î Follow(A)
• Τα στοιχεία του ΠΑ που δεν έχουν οριστεί με τα βήματα 1 και 2 θα έχουν τιμή error

(1) F à T id (A)
Ισχύει ότι First(T id (A)) = { id } , άρα προσθέτουμε τον κανόνα (1) στη θέση Μ[F, id] του πίνακα.
(2) T à id X
Ισχύει ότι First(id X) = { id } , άρα προσθέτουμε τον κανόνα (2) στη θέση Μ[T, id] του πίνακα.
(3) X à *X
Ισχύει ότι First(*X) = { * }, άρα προσθέτουμε τον κανόνα (3) στη θέση Μ[X, *] του πίνακα.
(4) X à ε
Ισχύει ότι First(ε) = { ε }, οπότε χρησιμοποιούμε το σύνολο Follow(Χ) και προσθέτουμε τον κανόνα
(4) στη θέση Μ[Χ, id] του πίνακα.
(5) Α à T id Z
Ισχύει ότι First(T id Z) = { id } , άρα προσθέτουμε τον κανόνα (5) στη θέση Μ[A, id] του πίνακα.
(6) A à ε
Ισχύει ότι First(ε) = { ε }, οπότε χρησιμοποιούμε το σύνολο Follow(A) και προσθέτουμε τον κανόνα
(6) στη θέση Μ[A, )] του πίνακα.
(7) Z à , T id Z
Ισχύει ότι First(, T id Z) = { , } , άρα προσθέτουμε τον κανόνα (7) στη θέση Μ[Z, ,] του πίνακα.
(8) Z à ε
Ισχύει ότι First(ε) = { ε }, οπότε χρησιμοποιούμε το σύνολο Follow(Z) και προσθέτουμε τον κανόνα
(8) στη θέση Μ[Z, )] του πίνακα.

Έτσι, έχουμε:

id * ( ) , $
F 1 - - - - -
T 2 - - - - -
X 4 3 - - - -
A 5 - - 6 - -
Z - - - 8 7 -
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

1.3 3η Άσκηση μεταγλωττιστές


Δίνεται η παρακάτω γραμματική:

(compilers_essay.3a.q)
Ως αρχικό σύμβολο θεωρήστε το σύμβολο GMPL. Τα τερματικά σύμβολα της γραμματικής είναι
τα start end fwd bwd ver hor και free.
Ερώτημα 1: Να συμπληρώσετε έναν πίνακα σαν τον παρακάτω για τα σύνολα First και Follow των
μη-τερματικών συμβόλων της γραμματικής. Στην απάντησή σας πρέπει, επίσης, να φαίνονται ανα-
λυτικά τα βήματα που κάνατε για να καταλήξετε στα σύνολα αυτά.

(compilers_essay.3b.q)
Ερώτημα 2: Να υπολογίσετε τον πίνακα ανίχνευσης του μοντέλου LL(1) ανίχνευσης για την γραμ-
ματική. Να αξιοποιήσετε την αρίθμηση των κανόνων της γραμματικής για τη συμπλήρωση του πί-
νακα.
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

Απάντηση
Ερώτημα 1
ΣΥΝΟΛΑ First
Για τον υπολογισμό των συνόλων First χρησιμοποιούμε τον αλγόριθμο:
Διακρίνουμε τις εξής περιπτώσεις για την προτασιακή μορφή :
1.εάν  είναι ένα γραμματικό σύμβολο ή , τότε
εάν  είναι ένα τερματικό a, τότε First() = First(a) = {a}
εάν  είναι το , τότε First() = First() = {}

εάν  είναι ένα μη-τερματικό Χ και Χ → β1 | β2 | … | βκ, τότε First() =


First(X) = First(β1)  First(β2)  …  First(βκ)
2.εάν  είναι μια συμβολοσειρά γραμματικών συμβόλων  = Χ1Χ2…ΧΝ, τότε
First()={}; j=0;
REPEAT
j=j+1;
Προσθέτουμε στο First() το First(Xj) – {}
UNTIL Xj δεν είναι απαλείψιμο (δεν παράγει το ) ή j=N
Εάν Χ1Χ2…ΧΝ, είναι απαλείψιμη, τότε προσθέτουμε το  στο First()
first(GMPL) = first(start GMPL CLIP end) + first(ver) =
{ start } + { ver } = { start, ver } (1),(2)
first(CLIP) = first(SUFF hor) + first(fwd GMPL
SUFF) + first(ε) = { bwd, hor } + { fwd } + { ε } = { bwd, hor, fwd, ε } (3),(4),(5),
(6),(7)
first(SUFF) = first(bwd GMPL CLIP free) + first(ε) =
{ bwd } + { ε } = { bwd, ε } (6),(7)

ΣΥΝΟΛΑ Follow
Για τον υπολογισμό των συνόλων Follow χρησιμοποιούμε τον αλγόριθμο:
Έστω G=(S, N, T, P), A  N και $ το τέλος μιας συμβολοσειράς
1. εάν Α = S, τότε $  Follow(Α)
2.  p  P, και Α περιλαμβάνεται στο δεξί μέρος του p με τη μορφή:
Β → γΑδ
i. εάν δ αρχίζει από τερματικό σύμβολο c, τότε c  Follow(Α)
ii. εάν δ αρχίζει από μη-τερματικό σύμβολο, τότε προσθέτουμε το First(δ) –
{}
iii. εάν δ= ή δ * , τότε προσθέτουμε το Follow(B)

Το GMPL είναι αρχικό σύμβολο της γραμματικής, άρα $  Follow(GMPL).


Το GMPL εμφανίζεται στο δεξί μέλος των κανόνων (1), (4) και (6) ακολουθούμενο από ένα
μη-τερματικό σύμβολο, άρα αντίστοιχα έχουμε:
First(CLIP end) – {ε} = { bwd, hor, fwd, end }  Follow(GMPL)
First(SUFF) – {ε} = { bwd }  Follow(GMPL) και
First(CLIP free) – {ε} = { bwd, hor, fwd, free }  Follow(GMPL)
Επιπλέον επειδή το SUFF είναι απαλείψιμο από τον κανόνα (4) προκύπτει
ότι Follow(CLIP)  Follow(GMPL).
Άρα:
Follow(GMPL) = { $, fwd, bwd, hor, end, free } + Follow(CLIP)

Το CLIP εμφανίζεται στο δεξί μέλος των κανόνων (1) και (6) ακολουθούμενο από ένα τερμα-
τικό σύμβολο, άρα:
Follow(CLIP) = {end} + {free} = { end, free }
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

Το SUFF εμφανίζεται στο δεξί μέλος των κανόνων (3) και (4) ακολουθούμενο από ένα τερμα-
τικό σύμβολο και από ε (άρα Follow(CLIP)  Follow(SUFF)), αντίστοιχα:
Follow(SUFF) = {hor} + Follow(CLIP) = { hor, end, free }

Έτσι, έχουμε:
First Follow
GMPL ver start $ fwd bwd end free hor
CLIP fwd bwd hor ε end free
SUFF bwd ε end free hor

Ερώτημα 2

Ο πίνακας ανίχνευσης ορίζεται εφαρμόζοντας τον παρακάτω αλγόριθμο:


• Για όλους τους κανόνες Aàa, εκτελούνται τα ακόλουθα βήματα:
1. για κάθε τερματικό σύμβολο b, όπου b Î First(a), προσθέτουμε τον κανόνα Aàa στη
θέση Μ[A, b]
2. εάν e Î First(a), τότε προσθέτουμε τον κανόνα Aàa στη θέση M[A, c] για κάθε τερ-
ματικό σύμβολο c που περιέχεται στο σύνολο Follow(A), επίσης προσθέτουμε τον κα-
νόνα Aàa στη θέση M[A, $], εάν $ Î Follow(A)
• Τα στοιχεία του ΠΑ που δεν έχουν οριστεί με τα βήματα 1 και 2 θα έχουν τιμή error

(1) GMPL à start GMPL CLIP end


Ισχύει ότι First(start GMPL CLIP end) = { start } , άρα προσθέτουμε τον κανόνα (1) στη θέση
Μ[GMPL, start] του πίνακα.
(2) GMPL à ver
Ισχύει ότι First(ver) = { ver } , άρα προσθέτουμε τον κανόνα (2) στη θέση Μ[GMPL, ver] του πίνακα.
(3) CLIP à SUFF hor
Ισχύει ότι First(SUFF hor) = { bwd, hor } , άρα προσθέτουμε τον κανόνα (3) στις θέσεις
Μ[CLIP, bwd] και Μ[CLIP, hor] του πίνακα.
(4) CLIP à fwd GMPL SUFF
Ισχύει ότι First(fwd GMPL SUFF) = { fwd } , άρα προσθέτουμε τον κανόνα (4) στη θέση
Μ[CLIP, fwd] του πίνακα.
(5) CLIP à ε
Ισχύει ότι First(ε) = { ε }, οπότε χρησιμοποιούμε το σύνολο Follow(CLIP) και προσθέτουμε τον κα-
νόνα (5) στις θέσεις Μ[CLIP, end] και Μ[CLIP, free] του πίνακα.
(6) SUFF à bwd GMPL CLIP free
Ισχύει ότι First(bwd GMPL CLIP free) = { bwd } , άρα προσθέτουμε τον κανόνα (6) στη θέση
Μ[SUFF, bwd] του πίνακα.
(7) SUFF à ε
Ισχύει ότι First(ε) = { ε }, οπότε χρησιμοποιούμε το σύνολο Follow(SUFF) και προσθέτουμε τον κα-
νόνα (7) στις θέσεις Μ[SUFF, end], Μ[SUFF, free] και Μ[SUFF, hor] του πίνακα.
Έτσι, έχουμε:

ver hor free fwd bwd start end $


GMPL 2 - - - - 1 - -
CLIP - 3 5 4 3 - 5 -
SUFF - 7 7 - 6 - 7 -
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

2. ΕΝΔΕΙΚΤΙΚΕΣ ΑΠΑΝΤΗΣΕΙΣ ΘΕΜΑΤΩΝ UML

2.1 1η Άσκηση UML

Δημιουργήστε διάγραμμα κλάσεων από τον παρακάτω κώδικα Java. Αγνοήστε τις κλάσεις
συστήματος.
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

Απάντηση
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

2.2 2η Άσκηση UML

Δημιουργήστε διάγραμμα κλάσεων από τον παρακάτω κώδικα Java. Αγνοήστε τις κλάσεις
συστήματος.
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

Απάντηση
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

2.3 3η Άσκηση UML

Δημιουργήστε διάγραμμα κλάσεων από τον παρακάτω κώδικα Java. Αγνοήστε τις κλάσεις
συστήματος.
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

Απάντηση
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

3. ΕΝΔΕΙΚΤΙΚΕΣ ΑΠΑΝΤΗΣΕΙΣ JAVA

3.1 1η Άσκηση Java

Μια εφαρμογή διαχειρίζεται αρχεία και φακέλους ενός μέσου αποθήκευσης Η/Υ. Συγκεκριμένα τόσο τα αρ-
χεία όσο και οι φάκελοι αποτελούν στοιχεία αρχειοθέτησης. Κάθε στοιχείο αρχειοθέτησης (αρχείο ή φάκε-
λος) εκτός από τον αρχικό φάκελο (root) μπορεί ανήκει σε κάποιο άλλο στοιχείο αρχειοθέτησης (φάκελος).
Ένας φάκελος μπορεί να περιέχει ένα σύνολο από στοιχεία αρχειοθέτησης (αρχεία και φακέλους).
Δίνεται η κλάση ArchiveElement η οποία αναφέρεται στα στοιχεία αρχειοθέτησης

η κλάση Folder η οποία αναφέρεται στους φακέλους

και η κλάση File η οποία αναφέρεται στα αρχεία

Δίνεται επίσης και τμήμα του κώδικα της main.


ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

α) Υλοποιήστε τον κατασκευαστή ArchiveElement(String name, ArchiveElement parent) στην κλάση Ar-
chiveElement. O κατασκευαστής θα πρέπει επιπλέον:
1. Να υλοποιεί έλεγχο ότι το αντικείμενο parent είναι φάκελος και όχι αρχείο. Σε περίπτωση που το
αντικείμενο είναι αρχείο να προκαλείται εξαίρεση.
2. Να ενημερώνεται το πεδίο elems του φακέλου στον οποίο θα ανήκει το στοιχείο αρχειοθέτησης
που δημιουργεί ο κατασκευαστής.
β) Στο σημείο Α της κλάσης ArchiveFile δημιουργήστε τα παρακάτω στοιχεία αρχειοθέτησης:
• Φάκελο με όνομα Tmp που είναι ο αρχικός φάκελος.
• Φάκελο με όνομα Backup που ανήκει στο φάκελο Tmp.
• Αρχείο με όνομα Note1.txt που έχει μέγεθος 45.2 και ανήκει στο φάκελο Tmp.
• Αρχείο με όνομα Note2.txt που έχει μέγεθος 32.6 και ανήκει στο φάκελο Backup.
• Αρχείο με όνομα Note3.txt που έχει μέγεθος 12.2 και ανήκει στο φάκελο Backup.

γ) Υλοποιήστε τη μέθοδο getSize(), η οποία θα επιστρέφει το μέγεθος ενός αρχείου ή ενός φακέλου. Το μέ-
γεθος ενός φακέλου υπολογίζεται ως το άθροισμα των μεγεθών των στοιχείων αρχειοθέτησης που περιέ-
χει.
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

Απάντηση
Ερώτημα Α
ΚΛΑΣΗ ArchiveElement

public ArchiveElement (String name, ArchiveElement parent) throws Ex-


ception{
this.name = name;
this.parent=parent;
if ((parent!=null)){
if (parent instanceof Folder) {
((Folder)parent).elems.add(this);}
else {
throw new Exception("Argument parent must be
Folder");}
}
}

ΚΛΑΣΗ Folder

public Folder(String name, ArchiveElement parent) throws Exception {


super(name,parent);
elems = new ArrayList<ArchiveElement>();
}

ΚΛΑΣΗ File

public File(String name, Float size, ArchiveElement parent) throws Ex-


ception {
super(name,parent);
this.size=size;
}

Ερώτημα Β

ΚΛΑΣΗ ArchiveFile

public static void main(String[] args) throws Exception {


ArrayList<ArchiveElement> elems=new ArrayList();

Folder f1=new Folder("Tmp",null);


Folder f2=new Folder("Backup",f1);
File fl1=new File("Note1.txt",45.2f,f1);
File f21=new File("Note2.txt",32.6f,f2);
File f22=new File("Note3.txt",12.2f,f2);
elems.add(f1);
elems.add(f2);
elems.add(fl1);
elems.add(f21);
elems.add(f22);

for (ArchiveElement f: elems) {


System.out.println(f.name+" has size "+f.getSize());
}
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

Ερώτημα Γ

ΚΛΑΣΗ ArchiveElement

public float getSize(){


return 0f;
}

ΚΛΑΣΗ Folder

public float getSize(){


float sz=0.f;
for (ArchiveElement e: elems){
sz=sz+e.getSize();
}
return sz;
}

ΚΛΑΣΗ File

public float getSize(){


return size;
}
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

3.2 2η Άσκηση Java

Μια εφαρμογή διαχειρίζεται αρχεία τραγουδιών και λίστες αρχείων τραγουδιών. Συγκεκριμένα τόσο τα αρ-
χεία τραγουδιών όσο και οι λίστες αποτελούν στοιχεία αρχειοθέτησης. Κάθε στοιχείο αρχειοθέτησης (τρα-
γούδι ή λίστα) μπορεί να ανήκει σε κάποιο άλλο στοιχείο αρχειοθέτησης (λίστα). Μια λίστα μπορεί να πε-
ριέχει ένα σύνολο από στοιχεία αρχειοθέτησης (τραγούδια και λίστες).
Δίνεται η κλάση ArciveElement η οποία αναφέρεται στα στοιχεία αρχειοθέτησης.

η κλάση SongList η οποία αναφέρεται στις λίστες τραγουδιών

και η κλάση SongFile η οποία αναφέρεται στα αρχεία τραγουδιών

Δίνεται επίσης και τμήμα του κώδικα της main.


ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

α) Υλοποιήστε τον κατασκευαστή ArchiveElement(String name, ArchiveElement parent) στην κλάση Ar-
chiveElement. O κατασκευαστής θα πρέπει επιπλέον:
1. Να υλοποιεί έλεγχο ότι το αντικείμενο parent είναι λίστα τραγουδιών και όχι αρχείο τραγουδιού.
Σε περίπτωση που το αντικείμενο είναι αρχείο τραγουδιού να προκαλείται εξαίρεση.
2. Να ενημερώνεται το πεδίο elems της λίστας τραγουδιών στην οποία θα ανήκει το στοιχείο αρ-
χειοθέτησης που δημιουργεί ο κατασκευαστής.
β) Στο σημείο Α της κλάσης ArchiveFile δημιουργήστε τα παρακάτω στοιχεία αρχειοθέτησης:
• Λίστα τραγουδιών με όνομα «Νησιώτικα 1».
• Λίστα τραγουδιών με όνομα «Νησιώτικα 2» που περιέχεται στη λίστα τραγουδιών «Νησιώτικα 1».
• Αρχείο τραγουδιού με τίτλο «Λυγαριά», έχει διάρκεια 125 sec και ανήκει στη λίστα «Νησιώτικα 1».
• Αρχείο τραγουδιού με τίτλο «Ικαριώτικο», έχει διάρκεια 205 sec και ανήκει στη λίστα «Νησιώτικα 2».
• Αρχείο τραγουδιού με τίτλο «Λυγαριά», έχει διάρκεια 125 sec και ανήκει στη λίστα «Νησιώτικα 2».

γ) Υλοποιήστε τη μέθοδο getDuration(), η οποία θα επιστρέφει τη διάρκεια ενός αρχείου τραγουδιού ή μιας
λίστας τραγουδιών. Η διάρκεια μια λίστας τραγουδιών υπολογίζεται ως το άθροισμα των διαρκειών των
στοιχείων αρχειοθέτησης που περιέχει.

Απάντηση
Ερώτημα Α

ΚΛΑΣΗ ArchiveElement

public ArchiveElement (String name, ArchiveElement parent) throws Exception{


this.name = name;
this.parent=parent;
if ((parent!=null)){
if (parent instanceof SongList) {
((SongList)parent).elems.add(this);}
else {
throw new Exception("Argument parent must
be SongList");}
}
}

ΚΛΑΣΗ SongList

public SongList(String name, ArchiveElement parent) throws Exception {


super(name,parent);
elems = new ArrayList<ArchiveElement>();
}
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

ΚΛΑΣΗ SongFile

public SongFile(String name, Float duration, ArchiveElement parent) throws


Exception {
super(name,parent);
this.duration=duration;
}

Ερώτημα Β

ΚΛΑΣΗ ArchiveFile

public static void main(String[] args) throws Exception {


ArrayList<ArchiveElement> elems=new ArrayList();

SongList l1=new SongList("Νησιώτικα 1",null);


SongList l2=new SongList("Νησιώτικα 2",l1);
SongFile s11=new SongFile("Λυγαριά",125f,l1);
SongFile s21=new SongFile("Ικαριώτικο",205f,l2);
SongFile s22=new SongFile("Λυγαριά",125f,l2);
elems.add(l1);
elems.add(l2);
elems.add(s11);
elems.add(s21);
elems.add(s22);

for (ArchiveElement f: elems) {


System.out.println(f.name+" has size "+f.getSize());
}
}

Ερώτημα Γ
ΚΛΑΣΗ ArchiveElement

public float getDuration(){


return 0f;
}

ΚΛΑΣΗ SongList

public float getDuration(){


float dr=0.f;
for (ArchiveElement e: elems){
dr=dr+e.getDuration();
}
return dr;
}

ΚΛΑΣΗ SongFile

public float getDuration(){


return duration;
}
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

3.3 3η Άσκηση Java

Φτιάξτε μια εφαρμογή η οποία να ελέγχει αν ο αριθμός μιας κάρτας είναι σωστός ή όχι. Το σύστημα θα
υποστηρίζει δύο είδη καρτών, τις πιστωτικές και τις χρεωστικές.
Ο κωδικός μιας κάρτας αποτελείται από 10 ψηφία.
Α) Για την πιστωτική κάρτα ο έλεγχος γίνεται ως εξής:
1) Το τελευταίο ψηφίο είναι το ψηφίο ελέγχου και αφαιρείται
2) Τα υπόλοιπα ψηφία αντιστρέφονται
3) Τα νούμερα στις μονές θέσεις διπλασιάζονται. Αν το νούμερο έχει δύο ψηφία τα αθροίζουμε
ώστε να προκύψει ένα ψηφίο
4) Προσθέτουμε όλα τα ψηφία
5) Αφαιρούμε από το 10 το τελευταίο ψηφίο του αριθμού του βήματος 4
Παράδειγμα
Ο αριθμός κάρτας είναι 1234567897
Βήμα 1 --> 123456789
Βήμα 2 --> 987654321
Βήμα 3 --> 9*2 --> 18--> 1+8=9
7*2-->14 --> 1+4=5
5*2-->10 -->1+0=1
3*2--> 6
1*2-->2
Ο αριθμός γίνεται 9 8 5 6 1 4 6 2 2
Βήμα 4 --> Προσθέτουμε τους αριθμούς
9+8+5+6+1+4+6+2+2 =43
Βήμα 5 --> 10-3 = 7 (κρατάμε το 3 από τον αριθμό 43)
Ο αριθμός 7 είναι ίδιος με το ψηφίο ελέγχου άρα ο αριθμός της κάρτας είναι σωστός.
Β) Για τη χρεωστική κάρτα θα γίνεται ο ίδιος έλεγχος και ελέγχουμε επίσης αν το νούμερο CSV (ένα τριψή-
φιο νούμερο που βρίσκεται στο πίσω μέρος της κάρτας) είναι ίδιο με τα 3 πρώτα ψηφία της κάρτας. Το
CVC θα δίνεται κατά την κατασκευή του αντικειμένου.
Θα πρέπει να δημιουργηθεί πρόγραμμα το οποίο υλοποιεί τις παρακάτω κλάσεις μαζί με τις απαιτούμενες
μεθόδους:
a) Card b) CreditCard c) DebitCard και d) CheckCard που περιέχει τη μέθοδο main.
Η εφαρμογή θα υλοποιεί τον παραπάνω αλγόριθμο και θα δημιουργεί 4 κάρτες
• δύο πιστωτικές, μια με σωστό νούμερο και μια με λανθασμένο και
• δύο χρεωστικές, μία με σωστό νούμερο και μια με λανθασμένο
Στη συνέχεια, να καλείται μέθοδος η οποία θα τυπώνεται το είδος της κάρτας, το νούμερο της κάρτας και
αν είναι σωστό ή λανθασμένο.
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

Απάντηση

Κλάση CheckCard

public class CheckCard {


public static void main(String[] args) {
// TODO code application logic here

CreditCard crCard1 = new CreditCard((long) 1234567897);


System.out.println(crCard1.toString());

CreditCard crCard2 = new CreditCard((long) 1234567895);


System.out.println(crCard2.toString());

DebitCard dbtCard1 = new DebitCard((long) 1234567897, 123);


System.out.println(dbtCard1.toString());

DebitCard dbtCard2 = new DebitCard((long) 1234567896, 123);


System.out.println(dbtCard2.toString());

DebitCard dbtCard3 = new DebitCard((long) 1234567897, 333);


System.out.println(dbtCard3.toString());
}
}

Κλάση Card

package checkcard;

public abstract class Card {

long cardNumber;
boolean cardType; // true for credit card false for debit

public Card(long num)


{
this.cardNumber=num;
}

public long getCardNumber()


{
return this.cardNumber;
}

public Boolean getCardType()


{
return this.cardType;
}

public String getCardTypeS()


{
if (cardType)
return "CREDIT ";
else
return "DEBIT ";
}
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

public boolean validateCard() {

long num=cardNumber;
// get check digit
int check=(int)(num%10);

// BHMA 1 - EXTRACT CHECK DIGIT


num= num/10;

// BHMA 2 - REVERSE DIGITS


String s=new StringBuilder(""+num).reverse().toString();
if (!(s.length()==9 ))
return false;

int sum=0;

for (int n=0; n<s.length(); n++) {

// BHMA 3 - DOUBLE DIGIT VALUE


int next = n%2==0 ? Integer.parseInt(s.substring(n, n+1))*2 :
Integer.parseInt(s.substring(n, n+1)) ;

if (next>9)
next=(next%10) + (next/10);

// Βήμα 4 - Προσθέτουμε όλα τα ψηφία


// Δεν χρειάζεται να ξανακατασκευάσουμε τον αριθμό. Απλά
προσθέτουμε.
sum+=next;
}

// Βήμα 5 - Αφαιρούμε από το 10 το τελευταίο ψηφίο του αριθμού του


βήματος 4
if (10-sum%10==check)
return true;
else
return false;

}
}

Κλάση CreditCard

package checkcard;

//Για τη χρεωστική κάρτα θα γίνεται ο ίδιος έλεγχος και ελέγχουμε επίσης // αν


το νούμερο CSV (ένα τριψήφιο νούμερο που βρίσκεται στο πίσω μέρος // της
κάρτας)
//είναι ίδιο με τα 3 πρώτα ψηφία της κάρτας. Το CVC θα δίνεται κατά την //
κατασκευή του αντικειμένου.

public class CreditCard extends Card {

public CreditCard(long num)


{
super(num);
this.cardType=true;
}

@Override
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

public String toString()


{
if (super.validateCard())
return getCardTypeS()+"Card with number :" + getCardNumber()+"
is Correct";
else
return getCardTypeS()+"Card with number :" + getCardNumber()+"
is NOT Correct";
}
}

Κλάση DebitCard

package checkcard;

public class DebitCard extends Card{

private int cvcNum;

public DebitCard(long num, int cvc)


{
super(num);
this.cardType=false;
this.cvcNum=cvc;

@Override
public boolean validateCard() {

boolean firstCheckResult;
boolean secondCheckResult;

firstCheckResult=super.validateCard();

String s=new StringBuilder(""+cardNumber).toString();

// CHECK THREE DIGITS


if (Integer.parseInt(s.substring(0, 3))== this.cvcNum)
secondCheckResult = true;
else
secondCheckResult = false;

return firstCheckResult && secondCheckResult;


}

@Override
public String toString()
{
if (validateCard())
return getCardTypeS()+"Card with number :" + getCardNumber()+"
and CVC number "+this.cvcNum+" is Correct";
else
return getCardTypeS()+"Card with number :" + getCardNumber()+"
and CVC number "+this.cvcNum+" is NOT Correct";
}
}
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

3.4 4η Άσκηση Java


Φτιάξτε μια εφαρμογή η οποία θα παράγει τον αριθμός μιας κάρτας μέλους μιας εμπορικής αλυσίδας. Το
σύστημα θα υποστηρίζει δύο είδη καρτών, τις απλές και τις επαγγελματικές.
Κάθε κάρτα χαρακτηρίζεται από το ονοματεπώνυμο του κατόχου, ημερομηνία λήξης και ένα κωδικό. Ο
κωδικός μιας κάρτας αποτελείται από 8 ψηφία.
Α) Για την απλή κάρτα ο αριθμός παράγεται ως εξής:
1) Παράγουμε ένα τυχαίο 7ψήφιο αριθμό με τη χρήση της κλάσης Random.
2) Aντιστρέφουμε τα ψηφία
3) Τα νούμερα στις ζυγές θέσεις διπλασιάζονται. Αν το νούμερο που προκύπτει έχει δύο ψηφία τα
αθροίζουμε ώστε να προκύψει ένα ψηφίο
4) Προσθέτουμε όλα τα ψηφία
5) Αφαιρούμε από το 10 το τελευταίο ψηφίο του αριθμού που προκύπτει από το βήμα 4 και το
προσθέτουμε ως 8ο ψηφίο στο αριθμό που έχει προκύψει από το βήμα 3.
Παράδειγμα
Έστω ότι παράγεται ο τυχαίος αριθμός 5632167
Βήμα 1 --> 5632167
Βήμα 2 --> 7612365
Βήμα 3 --> 6*2 --> 12--> 1+2=3
2*2-->4
6*2 --> 12--> 1+2=3
Ο αριθμός γίνεται 7 3 1 4 3 3 5
Βήμα 4 --> Προσθέτουμε τους αριθμούς
7 + 3 + 1 + 4 + 3 + 3 + 5 = 26
Βήμα 5 --> 10-6 = 4 (κρατάμε το 6 από τον αριθμό 26)
Ο αριθμός 4 προστίθεται στον αριθμό από το βήμα 3 και προκύπτει ως αριθμός κάρτας ο αριθμός 7 3 1 4 3
3 5 4.
Β) Για τη επαγγελματικές κάρτες θα γίνεται η ίδια διαδικασία παραγωγής αλλά θα προστίθεται στην αρχή
του αριθμού ο χαρακτήρας ΄Ε΄.
Θα πρέπει να δημιουργηθεί πρόγραμμα το οποίο υλοποιεί τις παρακάτω κλάσεις μαζί με τις απαιτούμενες
μεθόδους:
a) Card b) SimpleCard c) BussinessCard και d) GenerateCards που περιέχει τη μέθοδο main.
Η εφαρμογή θα υλοποιεί τον παραπάνω αλγόριθμο και θα δημιουργεί 4 κάρτες
• δύο απλές κάρτες και
• δύο επαγγελματικές κάρτες
Στη συνέχεια, να καλείται μέθοδος η οποία θα τυπώνει το ονοματεπώνυμο του κατόχου, το είδος της κάρ-
τας, το νούμερο της κάρτας και την ημερομηνία λήξης.

Απάντηση

Κλάση GenerateCard

package GenerateCards;
import java.util.Date;

public class GenerateCard {


public static void main(String[] args) {

SimpleCard sCard1;
sCard1 = new SimpleCard("PANOS FITSILIS", new Date(2022,12,31));
System.out.println(sCard1.toString());
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

SimpleCard sCard2 = new SimpleCard("CHRISTOS KOUTSIKAS", new


Date(2024,4,24));
System.out.println(sCard2.toString());

BusinessCard bCard1 = new BusinessCard("TAKIS ALEFRAGKIS", new


Date(2034,5,5));
System.out.println(bCard1.toString());

BusinessCard bCard2 = new BusinessCard("DIONISIS ADAMOPOULOS", new Date


(2030,6,6));
System.out.println(bCard2.toString());
}
}

Κλάση Card

package GenerateCards;

import java.util.Date;
import java.util.Random;

public abstract class Card {

final int maxCardNumber = 9999999;

String cardNumber;
String ownerName;
Date expireDate;
boolean cardType; // true for sumple card false for business card

public Card(String ownerName, Date expireDate)


{
this.cardNumber=generateCardNumber();
this.ownerName = ownerName;
this.expireDate = expireDate;

public String getCardNumber()


{
return this.cardNumber;
}

public Boolean getCardType()


{
return this.cardType;
}

public String getCardTypeS()


{
if (cardType)
return "SIMPLE ";
else
return "BUSINESS ";
}

public String getOwnerName()


{
return this.ownerName;
}
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

public Date getExpiredate()


{
return this.expireDate;
}

public String generateCardNumber() {

// BHMA 1 - PRODUCE RANDOM NUMBER FROM 0 TO MANCARDNUMBER


int checkDigit =0;
int tempCardNumber;
Random random = new Random();
tempCardNumber = random.nextInt(maxCardNumber);

// BHMA 2 - REVERSE DIGITS


String s=new StringBuilder(""+tempCardNumber).reverse().toString();

int sum=0;

for (int n=0; n<s.length(); n++) {

// BHMA 3 - DOUBLE DIGIT VALUE


int next = n%2==1 ? Integer.parseInt(s.substring(n, n+1))*2 :
Integer.parseInt(s.substring(n, n+1)) ;

if (next>9)
next=(next%10) + (next/10);

// Βήμα 4 - Προσθέτουμε όλα τα ψηφία


// Δεν χρειάζεται να ξανακατασκευάσουμε τον αριθμό. Απλά
προσθέτουμε.
sum+=next;
}

// Βήμα 5 - Παράγουμε το check digit


checkDigit = 10-sum%10;

String finalCardNumber = new


StringBuilder(""+tempCardNumber).toString();
finalCardNumber = finalCardNumber + checkDigit;

return finalCardNumber;
}

public String toString()


{
return getCardTypeS()+"Card with number : " + getCardNumber()+"\n"
+"Card type : "+getCardTypeS()+"\n"
+"Owner name : "+ getOwnerName()+"\n"
+"Expire Date: "+getExpiredate()+"\n";

}
}

Κλάση SimpleCard

package GenerateCards;

import java.util.Date;
ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΠΛΗ24 «ΣΧΕΔΙΑΣΜΟΣ ΛΟΓΙΣΜΙΚΟΥ»
ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ: 2020-2021

// Για τη χρεωστική κάρτα θα γίνεται ο ίδιος έλεγχος και ελέγχουμε επίσης αν το


// νούμερο CSV (ένα τριψήφιο νούμερο που βρίσκεται στο πίσω μέρος της κάρτας)
// είναι ίδιο με τα 3 πρώτα ψηφία της κάρτας. Το CVC θα δίνεται κατά την
// κατασκευή του αντικειμένου.

public class SimpleCard extends Card {

public SimpleCard(String owner, Date expDate)


{
super(owner, expDate);
this.cardType=true;
}
}

Κλάση BusinessCard

package GenerateCards;

import java.util.Date;

public class BusinessCard extends Card{

private int cvcNum;

public BusinessCard(String ownerName, Date expireDate)


{
super(ownerName, expireDate);
this.cardType=false;

@Override
public String generateCardNumber() {

return "E"+super.generateCardNumber();
}
}

You might also like