המכללה האקדמית ת"א-יפו

‫המכללה האקדמית ת"א‪-‬יפו‪ ,‬ביה"ס למדעי המחשב‬
‫חישוביות ‪ -‬פתרון דף תרגילים מספר ‪1‬‬
‫שאלה ‪1‬‬
‫סעיף א'‬
‫‪(a.(a.nil)) .1‬‬
‫‪((a.nil).((a.nil).nil)) .2‬‬
‫‪(((a.(a.nil)).nil).nil) .3‬‬
‫‪((a.nil).((a.(a.nil)).nil)) .4‬‬
‫‪(((a.nil).((a.nil).nil)).(a.nil)) .5‬‬
‫סעיף ב'‬
‫כתיב עצים‪ ((nil.nil).((nil.nil).nil)) :‬כתיב רשימות‪ ((( )) (( ))) :‬או ))‪((nil) (nil‬‬
‫שאלה ‪2‬‬
‫שימו לב כי הגדרת השפה ‪ WHILE-R‬מחלקת את מחלקת הפקודות לשני סוגים ‪ -‬אלו שמותר לשים‬
‫כביטוי בתנאי ‪ /‬לולאה ולשרשר (פקודת ההשמה)‪ ,‬ואילו שלא (שאר הפקודות)‪ .‬לכן נגדיר מחלקה‬
‫תחבירית חדשה‪ ,‬נקרא לה ‪ ,Assignment‬שתכלול רק את משפט ההשמה‪ .‬יש להיזהר ולא לכלול את‬
‫פקודת ההשמה במחלקת הביטויים (פתרון שנראה לכאורה נכון וקל) שכן זה יאפשר כתיבת ביטויים כגון‬
‫‪X:= hd tl Y:=Z‬‬
‫שאינם חוקיים גם ב‪ .WHILE-R -‬טבלת התחביר המופשט של ‪ WHILE-R‬יכלה להיראות כך ‪:‬‬
‫‪Expression ::= X‬‬
‫‪d‬‬
‫|‬
‫‪hd E‬‬
‫|‬
‫‪tl E‬‬
‫|‬
‫‪cons E F‬‬
‫|‬
‫‪E, F ‬‬
‫‪A  Assignment ::= X := A‬‬
‫‪| X:= E‬‬
‫‪C, D  Command ::= C ; D‬‬
‫‪A‬‬
‫|‬
‫‪while E do C‬‬
‫|‬
‫‪if E then C else D‬‬
‫|‬
‫‪while A do C‬‬
‫|‬
‫‪if A then C else D‬‬
‫|‬
‫‪Program ::= read X ; C; write Y‬‬
‫‪X  Variable‬‬
‫‪d ID‬‬
‫תחביר מופשט לשפת ‪W‬‬
3 ‫שאלה‬
.‫א‬
read X;
while X do {
Y := cons nil Y;
X := tl X
};
write Y
.O(#X) ‫ כלומר‬,‫התכנית רצה בסיבוכיות לינארית באורך הקלט‬
.‫ב‬
read Inp;
I := hd Inp;
L := hd tl Inp;
I := tl I;
while I do {
L := tl L;
I := tl I };
Y := hd L;
write Y
// input: (i L)
.O(i) ‫ כלומר‬,i ‫התכנית רצה בסיבוכיות לינארית בערך‬
.‫ג‬
read Inp;
// input: (i d L)
I := hd Inp;
D := hd tl Inp;
L := hd tl tl Inp;
R := nil;
I := tl I;
while I do { // move elements from L to R until we reach the desired point
R := cons (hd L) R;
L := tl L;
I := tl I
};
L := cons D (tl L);
// put D instead of the head of L
while R do {
// move elements from R back to L.
L := cons (hd R) L;
R := tl R};
write L
.O(i) ‫ כלומר‬,i ‫התכנית רצה בסיבוכיות לינארית בערך‬
.‫ד‬
read Inp;
I := hd Inp;
D := hd tl Inp;
L := hd tl tl Inp;
// input: (i d L)
Y := “(nil)”
if I then
I := tl I
else
Y := nil;
while I do { // move elements from L to R until we reach the desired point
if L then {
R := cons (hd L) R;
L := tl L;
I := tl I }
else {
I := nil;
Y := nil;
}
};
if Y then
L := tl L
// remove i element from L.
else
L := L;
// index out of range don’t change L.
while R do {
// move elements from R back to L.
L := cons (hd R) L;
R := tl R};
write L
.O(i) ‫ כלומר‬,I ‫התכנית רצה בסיבוכיות לינארית בערך‬
.‫ה‬
read Inp;
// input: (L1 L2)
L1 := hd Inp;
L2 := hd (tl Inp);
while L1 do { // move all elements from L1 to R.
R := cons (hd L1) R;
L1:= tl L1
};
while R do {
// move elements from R to L2.
L2 := cons (hd R) L2;
R := tl R
};
write L2
.O(#L1) ‫ כלומר‬,‫התכנית רצה בסיבוכיות לינארית באורך של הרשימה הראשונה‬
4 ‫שאלה‬
:)‫ התוכנית בתחביר מופשט (עם שמות משתנים שרירותיים‬.‫א‬
read X
if (hd X) then
Y := X
else {
while (tl X) do
‫")‪Y := “(nil nil nil‬‬
‫;}‬
‫‪write Y‬‬
‫ב‪ .‬אם הקלט הוא עץ שראשו איננו ‪ ,nil‬הפלט יהיה שווה לקלט (עקב ביצוע ‪.)Y := X‬‬
‫אחרת (כלומר אם ‪ hd X‬נותן ‪ ,)nil‬אם הזנב איננו ‪ ,nil‬התוכנית תיכנס ללולאה אינסופית ולא תחזיר פלט‬
‫כלל‪ .‬לבסוף‪ ,‬אם העץ הוא ‪ nil‬או )‪ ,(nil.nil‬התוכנית תחזיר ‪( nil‬בשני מקרים אלה הולכים ל‪ else-‬אך‬
‫הלולאה איננה מבוצעת)‪ .‬באופן פורמלי ‪:‬‬
‫‪,d = (h . t)  h  nil‬‬
‫‪,d = (nil. t)  t  nil‬‬
‫)‪d = nil  d=(nil.nil‬‬
‫ג‪ .‬הפלט יהיה שווה לקלט‪.‬‬
‫‪d‬‬
‫‪‬‬
‫‪nil‬‬
‫{‬
‫= ‪[[p]]d‬‬