650 likes | 1.12k Views
חשיבה תכנותית – חלק 3 בקרת זרימה: לולאות. קרן כליף. ביחידה זו נלמד:. לולאות הצגת הפתרון תרשים זרימה כתיבת הפתרון בפסאודו-קוד לולאות מקוננות. חישוב סכום ספרותיו של מספר. בהינתן מספר שלם חיובי כלשהו, נרצה למצוא את סכום ספרותיו דוגמאות: 347 3+4+7=14 2251 2+2+5+1=10.
E N D
חשיבה תכנותית – חלק 3בקרת זרימה: לולאות קרן כליף
ביחידה זו נלמד: • לולאות • הצגת הפתרון תרשים זרימה • כתיבת הפתרון בפסאודו-קוד • לולאות מקוננות
חישוב סכום ספרותיו של מספר • בהינתן מספר שלם חיובי כלשהו, נרצה למצוא את סכום ספרותיו • דוגמאות: • 347 3+4+7=14 • 2251 2+2+5+1=10
חישוב סכום ספרותיו של מספר – ההוראות בהן מותר להשתמש • "תן ספרה ימנית" • דוגמא: 347 7 • "קצץ ספרה ימנית" • דוגמא: 347 34 • קיצוץ מספר חד ספרתי מחזיר את הערך 0 • אסטרטגיית הפעולה: לעבור על כל אחת מספרות המספר ולהוסיף אותה לסכום • מאחר ובכל שלב יש לנו גישה רק לספרה הימנית ביותר, יהיה עלינו לקצץ אותה כדי להגיע לספרה שלידה • כאשר נסיים לקצץ את כל הספרות (כלומר הערך שישאר לנו יהיה 0), נדע שסיימנו את העבודה
חישוב סכום ספרותיו של מספר – תרשים זרימה זוהי הנקודה בה אנו מחליטים האם לבצע את כל התהליך פעם נוספת, או לצאת נשים לב שערכו המקורי של X נהרס
חישוב סכום ספרותיו של מספר – תרשים זרימה במקרה זה שמרנו את ערכו של X ב- temp וכך ערכו המקורי של X נשמר
חישוב סכום ספרותיו של מספר – כתיבה פורמאלית הרצה יבשה: • הגדר sum=0 • קלוט מספר לתוך X • הגדר temp=X • כל עוד temp > 0: • תן ספרה ימנית מ- temp והוסף אותה ל- sum • קצץ מ- temp ספרה ימנית • הצג את sum sum = 0 sum = 2 sum = 9 sum = 13 X = 472 temp = 472 temp = 47 temp = 4 temp = 0 שימוש במושג "כל עוד" מעיד על קטע שיש לחזור עליו
חישוב ממוצע • יש לקלוט מספרים עד אשר יקלט מספר שלילי. יש להציג את ממוצע המספרים (לא כולל המספר השלילי שהוכנס). זוהי הנקודה בה אנו מחליטים האם לבצע את כל התהליך פעם נוספת, או לצאת מה יקרה אם כבר במספר הראשון יוקלד ערך שלילי?
חישוב ממוצע: כתיבה פורמאלית • הגדר counter=0, sum=0 • קלוט מספר X • כל עוד 0 ≤ X: • הוסף את X ל- sum • הגדל את counter ב- 1 • קלוט מספר נוסף ל- X • אם ערכו של counter הוא 0: • הצג: "לא הוקלדו מספרים חיוביים" • אחרת: • הצג את תוצאת החישוב sum/counter הרצה יבשה, למשל עבור 7 2 1-: sum = 0 sum = 7 sum = 9 counter = 0 counter = 1 counter = 2 X = 7 X = 2 X = 1- נשים לב: בכתיבה פורמאלית ניתן לחזור רק לקטע המתחיל ב"כל עוד", ולכן סעיף 2 כתוב שוב בתור סעיף 3C
יצירת המספר ההופכי • למשל, עבור 123 יש לייצר את המספר 321 • גם במקרה זה צריך לבודד את כל אחת מהספרות ולכן נשתמש בפעולות "תן/קצץ ספרה ימנית" • ניתן להשתמש גם בפעולות חשבון בסיסיות (כפל, חיבור וכד')
ובכתיבה פורמאלית • הגדר newNum = 0 • קלוט מספר לתוך X • הגדר temp = X • כל עוד temp > 0: • תן ספרה ימנית מ- temp והוסף אותה מימין ל- newNum • קצץ ספרה ימנית מ- temp • הצג את newNum הרצה יבשה: newNum = 0 newNum = 03 newNum = 032 newNum = 0321 X = 123 temp = 123 temp = 12 temp = 1 temp = 0 נשים לב שכאשר מבקשים מאיתנו לייצר מספר, אין ברשותנו את הפעולה:"הצמד ספרה לימין המספר"...
הוספת ספרה מימין למספר • כאשר רוצים להוסיף ספרה מימין למספר, כלומר להכניס ספרת אחדות חדשה, יש לבצע את הפעולות הבאות: • הכפל את המספר פי 10 (כדי לייצר מקום לספרת האחדות החדשה) • הוסף את הספרה החדשה • דוגמא: עבור המספר 65 נרצה להוסיף את הספרה 3 מימין, כלומר כדי לייצר את מספר 653: • 65*10 = 650 • 650 + 3 = 653
ובכתיבה פורמאלית • הגדר newNum = 0 • קלוט מספר לתוך X • הגדר temp = X • כל עוד temp > 0: • הכפל את הערך של newNum פי 10 • תן ספרה ימנית מ- temp והוסף אותה ל- newNum • קצץ ספרה ימנית מ- temp • הצג את newNum הרצה יבשה: newNum = 0 newNum = 30 newNum = 32 newNum = 321 newNum = 3 newNum = 320 X = 123 temp = 123 temp = 12 temp = 1 temp = 0
הוספת ספרות משמאל למספר • כאשר מוסיפים ספרה משמאלו של מספר יש לקחת בחשבון איזה מיקום היא תופסת: אחדות / עשרות / מאות וכד' • דוגמא: אם רוצים למספר 47 להוסיף את הספרה 3 משמאלו, למעשה יש להוסיף את הערך 300 • 47 + 300 = 347 • אם נרצה להוסיף ספרה נוספת משמאל, היא כבר תהייה במיקום של האלפים
הוספת ספרות משמאל למספר - דוגמא • נייצר את המספר 724 תוך כדי הוספת ספרות משמאלו: • 4 2 7 • בהתחלה המספר יהיה 0 • נוסיף למספר את הערך4 • 4*100 =4*1 = 4 • נוסיף למספר את הערך 20 • 2*101 =2*10 = 20 • נוסיף למספר את הערך 700 • 7*102 =7*100 = 700 • המספר המתקבל הוא 724 הרצה יבשה: המספר: 0 המספר: 4 המספר: 24 המספר: 724 ניתן לזהות את החוקיות שהוספת ספרה משמאל היא למעשה חזקה כלשהי של 10, שגדלה ב- 1 בכל פעם
יצירת מספר המכיל רק את הספרות הזוגיות • יש לקלוט מספר ולייצר מספר המכיל רק את הספרות שערכן זוגי • דוגמא: עבור המספר 123467 יווצר המספר 246 • הכלים העומדים לרשותינו הן הפעולות: • "תן/קצץ ספרה ימנית" • פעולות חשבון • בדיקה האם ערך הוא זוגי • במקרה זה עלינו להוסיף ספרות משמאלו של המספר המיוצר
יצירת מספר המכיל רק את הספרות הזוגיות ייצור הערך המתאים להוספה למספר נכפיל את location רק במידה והוספנו ספרה, כהכנת התשתית לספרה הבאה
ובכתיבה פורמאלית הרצה יבשה: • הגדר location=1, newNum=0 • קלוט ערך לתוך X • הגדר temp=X • כל עוד temp > 0: • תן ספרה ימנית של temp, ואם זוגית בצע: • הכפל את הספרה פי location והוסף אותה ל- newNum • הכפל location פי 10 • קצץ ספרה ימנית מ- temp • הצג את newNum newNum = 0 newNum = 8 newNum = 28 location = 1 location = 10 location = 100 X = 258 temp = 258 temp = 25 temp = 2 temp = 0
מיזוג ספרות של שני מספרים זהים באורכם • יש לקלוט 2 מספרים הזהים בכמות הספרות שלהם, ולייצר מספר חדש כך שהספרות בו הם מיזוג הספרות של שני המספרים: • ספרה ראשונה (משמאל) מהמספר הראשון וספרה שניה מהמספר השני • ספרה שלישית מהמספר הראשון וספרה רביעית מהמספר השני • וכו' • דוגמא: • עבור המספרים 37 ו- 81 יש לייצר את המספר 3871 • אסטרטגיית הפעולה: מאחר וניתן לבודד ספרות מימין לשמאל, בניית המספר החדש תתבסס על הוספת ספרות משמאל, כאשר מתחילים דווקא מהמספר השני
ובכתיבה פורמאלית הרצה יבשה: • קלוט מספר ל- num1 • קלוט מספר ל- num2 • הגדר newNum=0 • הגדר location=1 • כל עוד num2 > 0: • בודד ספרה ימנית מ- num2, הכפל אותה ב- location והוסף ל- newNum • הכפל את location פי 10 • בודד ספרה ימנית מ- num1, הכפל אותה ב- location והוסף ל- newNum • הכפל את location פי 10 • קצץ ספרה ימנית מ- num2 • קצץ ספרה ימנית מ- num1 • הצג את newNum newNum = 3871 newNum = 871 newNum = 71 newNum = 0 newNum = 1 location = 10000 location = 1000 location = 10 location = 100 location = 1 num1 = 37 num1 = 3 num1 = 0 num2 = 8 num2 = 81 num2 = 0
מציאת הספרה הגדולה ביותר • קלוט מהמשתמש מספר והצג את הספרה הגדולה ביותר. • דוגמאות: • עבור 1234 יוצג 4 • עבור 8997 יוצג 9 • עבור 1212 יוצג 2 • אסטרטגיית הפעולה: נאתחל את המקסימום עם ערך הספרה הראשונה (הימנית) ונבודד כל פעם ספרה אחרת. אם הספרה הנוכחית גדולה מהספרה המקסימלית שראינו עד כה, נעדכן אותה.
ובכתיבה פורמאלית • קלוט מהמשתמש מספר לתוך num • הגדר את maxDigit ואתחל אותה בספרה הימנית של num • קצץ ספרה ימנית מ- num • כל עוד נותרו ב- num ספרות (num>0): • תן ספרה ימנית מ- num ואחסן אותה בתוך temp • אם temp > maxDigit: • עדכן: maxDigit = temp • קצץ ספרה ימנית מ- num • הצג את maxDigit הרצה יבשה: num = 387 num = 38 num = 3 num = 0 maxDigit = 7 maxDigit = 8 temp = 8 temp = 3
זיהוי מספר יותר ארוך • יש לקלוט 2 מספרים (שאינם בהכרח באותו האורך), ולהגיד לאיזה מספר יש יותר ספרות, וכמה ספרות יותר יש בו. • דוגמא: • עבור המספר 1234 והמספר 99 יש לאמר שבמספר 1234 יש 2 ספרות יותר מאשר במספר השני. • אסטרטגיית הפעולה: • נקצץ ספרות משני המספרים בו-זמנית עד אשר לאחד יגמרו הספרות. • נתחיל לספור את כמות הספרות שיש לקצץ למספר שנותר עד אשר יגמרו גם לו הספרות.
תרשים זרימה מאחר ובסוף יש להציג גם מי המספר שיש בו יותר ספרות יש צורך לשמור את המספרים המקוריים ולעבוד עם temp כאשר מגיעים לפה בלפחות אחד מהמספרים כבר אין ספרות, לכן בוודאות ניכנס מקסימום לאחת מהלולאות שסופרות, מבלי צורך לבדוק מהו המספר שנותרו בו ספרות
הצגת כמות כלשהי של כוכביות • נרצה לקלוט מספר מהמשתמש, ולהציג כוכביות בכמות של המספר שנקלט • הפעולות שעומדות לרשותינו הן: • "הדפס כוכבית אחת" • פעולות חשבוניות • ניתן להבחין שבתרגיל זה יש תהליך שחוזר על עצמו, והוא הצגת כוכבית. • צריך לדאוג שתהליך זה יקרה בדיוק כמות מסוימת של פעמים
תרשים זרימה counter מכיל את כמות הכוכביות שהוצגו עד כה, ולכן בהתחלה מאותחל ל- 0 התהליך יחזור כל עוד לא הצגנו את כל כמות הכוכביות המבוקשת לאחר הצגת כוכבית, נעדכן את counter ע"י הגדלתו ב- 1
ובכתיבה פורמאלית • קלוט מספר X • הגדר counter=0 • כל עוד counter < X: • הצג כוכבית • הגדל את counter ב- 1 הרצה יבשה: X = 3 counter = 0 counter = 1 counter = 2 counter = 3 * * * המיוחד בדוגמא זו הוא שעם תחילת הלולאה, כבר ידועה כמות הסיבובים שהיא תבצע. למקרה זה יש את הפורמט שמוצג בשקף הבא..
ובכתיבה פורמאלית (2) בצורת כתיבה זו ערכו של i גדל ב-1 באופן אוטומטי בכל פעם, החל מ- 1 עד שערכו מגיע להיות X כולל • קלוט מספר X • עבור i בטווח 1...X: • הצג כוכבית הרצה יבשה: X = 3 i = 1 i = 2 i = 3 * * *
הצגת כל המספרים • יש לקלוט מהמשתמש מספר ולהציג את כל המספרים מ- 1 עד למספר זה. • זוהי למעשה בדיוק אותה בעיה כמו מקודם, רק הפעם במקום להדפיס כוכבית, יש להדפיס מספר. • קלוט מספר X • עבור i בטווח 1...X: • הצג את i
כתיבה פורמלית - דגשים • נקפיד על פשטות הטקסט, ונשתמש במושגים הבאים: • כל עוד <תנאי> – עבור תהליך שחוזר על עצמו כל עוד התנאי מתקיים • עבור i בטווח <התחלה>...<סוף> – עבור תהליך שחוזר על עצמו כמות ידועה של פעמים • אם <תנאי> אחרת – עבור ביצוע פעולות בעת קיום תנאי מסויים • נקפיד על כתיבה מדורגת (אינדנטציה) המשקפת את מבנה התוכנית
כללי אצבע לשאלות עם לולאות • כאשר מספר הסיבובים אינו ידוע מראש, למשל כאשר תלויים בקלט של המשתמש כל פעם נשתמש במבנה "כל עוד... • כאשר מספר הסיבובים ידוע עם תחילת הלולאה נשתמש במבנה "עבור i בטווח...", שכן מבנה זה כולל בתוכו את אתחול וקידום המונה
ציור מלבן • יש לקלוט מהמשתמש גובה ורוחב ולהציג מלבן של כוכביות לפי הכמויות שנקלטו • למשל עבור גובה 3 ורוחב 5 יוצג המלבן הבא: * * * * * * * * * * * * * * * • נשים לב שיש פה תהליך מרכזי שחוזר על עצמו 3 פעמים והוא הדפסת שורה • בכל הדפסת שורה יש תהליך שחוזר על עצמו והוא הדפסת כוכבית אחת ולבסוף ירידת שורה.
תרשים זרימה תהליך שחוזר על עצמו height פעמים בתוך התהליך המרכזי, ישנו תהליך נוסף שחוזר על עצמו width פעמים
ובכתיבה פורמאלית • קלוט width ו- height • עבור i בטווח 1...height: • עבור j בטווח 1...width: • הדפס כוכבית • רד שורה הרצה יבשה: width = 3 height = 2 i =1 i =2 j = 1 j = 2 j = 3 הספירה של j מתחילה מההתחלה * * * * * *
ציור משולש מוצמד לשמאל • יש לקלוט מהמשתמש אורך בסיס של משולש ולהציג משולש ישר-זוית של כוכביות, מוצמד לשמאל, שבסיסו כגודל שנקלט. • למשל, עבור בסיס בגודל 4 יודפס המשולש הבא: * * * * * * * * * * • נשים לב שיש פה תהליך מרכזי שחוזר על עצמו 4 פעמים והוא הדפסת שורה. העובדה שאורך השורות שונה אינה משנה! • בכל הדפסת שורה יש תהליך שחוזר על עצמו והוא הדפסת כוכבית אחת ולבסוף ירידת שורה.
ציור משולש מוצמד לשמאל: ניתוח הצורה • מאחר ובכל שורה כמות שונה של כוכביות, ננסה למצוא את החוקיות, ולכן נצייר את הטבלה הבאה: • ניתן לזהות קשר בין מספר הכוכביות למספר השורה: מספר הכוכביות הוא כמספר השורה * * * * * * * * * * * * * * *
תרשים זרימה הפעולות שבתוך חלק זה אמורות להדפיס שורה אחת כל פעם. i למעשה מייצג את מספר השורה שאנחנו כרגע מציירים. פעולה זו קובעת כמה כוכביות יודפסו. במקרה זה i, מאחר ו- i מיצג את מספר השורה, שערכה זהה למספר הכוכביות בשורה.
ובכתיבה פורמאלית • קלוט basis • עבור i בטווח 1...basis: • עבור j בטווח 1...i: • הדפס כוכבית • רד שורה הרצה יבשה: basis = 3 i =2 i =3 i =1 j = 3 j = 2 j = 1 הספירה של j מתחילה מההתחלה ורצה עד i המעודכן * * * * * *
ציור משולש מוצמד לשמאל שבסיסו למעלה • יש לקלוט מהמשתמש אורך בסיס של משולש ולהציג משולש ישר-זוית של כוכביות, מוצמד לשמאל, שבסיסו כגודל שנקלט, אבל הבסיס למעלה. • למשל, עבור בסיס בגודל 4 יודפס המשולש הבא: * * * * * * * * * * • גם בדוגמא זו יש תהליך מרכזי שחוזר על עצמו 4 פעמים והוא הדפסת שורה. העובדה שאורך השורות שונה אינה משנה! הגבלה: כל פלט תמיד יוצג מלמעלה למטה. כלומר, חובה עלינו להתחיל לצייר מהשורה הראשונה עם 4 הכוכביות עד האחרונה עם כוכבית אחת.
ציור משולש הפוך: ניתוח הצורה • מאחר ובכל שורה כמות שונה של כוכביות, ננסה למצוא את החוקיות, ולכן נצייר את הטבלה הבאה: • ניתן לזהות שמספר הכוכביות מהווה סדרה יורדת, החל מגודל הבסיס עד 1. • לכן ננסה למספר את השורות באופן שונה. * * * * * * * * * * * * * * *
תרשים זרימה הפעם ערכו של i קטן בכל סיבוב: החל מערכו של basis עד שהוא מגיע להיות 1.
ובכתיבה פורמאלית • קלוט basis • עבור i בטווח basis...1: • עבור j בטווח 1...i: • הדפס כוכבית • רד שורה הרצה יבשה: basis = 3 i = 3 i = 1 i =2 j = 1 j = 2 j = 3 * * * * * *
ציור טרפז • יש לקלוט את רוחבו העליון של טרפז ואת רוחבו התחתון. • ניתן להניח כי הרוחב העליון קצר מהרוחב התחתון. • יש לצייר טרפז בהתאם לרוחבים שנקלטו. • דוגמא: • עבור רוחב עליון 4 ורוחב תחתון 7 נצייר את הטרפז הבא: * * * * * * * * * * * * * * * * * * * * * * • כלומר, בשורה הראשונה 4 כוכביות, בשניה 5 וכך עד שיש שורה עם 7 כוכביות. • נשים לב שציור הכוכביות בכל שורה אינו בהכרח מתחיל מתחילת השורה!
ציור טרפז: ניתוח הבעיה • מאחר וכל שורה, פרט לאחרונה, אינה מתחילה צמודה לשמאל, יש למצוא דרך לצייר את הכוכביות יותר ימינה בשורה. • הדרך היא לצייר רווחים (תו שאינו נראה אך מקדם את המיקום) לפני ציור הכוכביות. • ניתן לראות שאכן בצד שמאל הטרפז נראה תקין, אבל צידו הימני ישר, ולכן ננסה לשים רווח בין כל כוכבית • ---*-*-*-* • --*-*-*-*-* • -*-*-*-*-*-* • *-*-*-*-*-*-* • ---**** • --***** • -****** • *******
ציור טרפז: ניתוח הבעיה (2) • ניתן לראות שכל שורה מורכבת מכמות כלשהי של רווחים, ואז זוגות של כוכבית+רווח, פרט לכוכבית האחרונה, שאין מימינה רווח • לצורך הכלליות, נצייר גם ליד הכוכבית האחרונה רווח (לא ישנה את התצוגה על המסך מאחר ורווח הוא תו שאינו נראה) • ---*-*-*-*- • --*-*-*-*-*- • -*-*-*-*-*-*- • *-*-*-*-*-*-*- • ---*-*-*-* • --*-*-*-*-* • -*-*-*-*-*-* • *-*-*-*-*-*-*
ציור טרפז: ניתוח הבעיה (3) • נצייר טבלה שבנוסף לכמות הצמדים של כוכבית+רווח בכל שורה, מציינת כמה רווחים יש לצייר בתחילת השורה • ---*-*-*-*- • --*-*-*-*-*- • -*-*-*-*-*-*- • *-*-*-*-*-*-*- הצגת הפלט הוא תמיד מלמעלה למטה, ומשמאל לימין, לכן עלינו להקפיד על ציור הרווחים בתחילת כל שורה.