הכנה לקראת שנה א' במדעי המחשב - עמוד 4 - לימודים והצעות עבודה - HWzone פורומים
עבור לתוכן
  • צור חשבון

הכנה לקראת שנה א' במדעי המחשב


ggg123

Recommended Posts

ניהלתי טבלת מעקב פשוטה של ערכים מ 2 עד 4. המספרים הראשוניים הם 2 ו 3 זאת אומרת שהפלט אמור להיות 5/2= 2.5. אכן יצא 2.5 בטבלת המעקב.

מצאתי בקוד שלי טעות בלולאה השנייה (כתבתי n<y וזה אמור להיות n<i) . תיקנתי את זה.

משום מה הקוד עדיין מוציא לי 3.0. כנראה הקוד שכתבתי לא פועל כמו שאני חושב ואני לא מוצא למה. אני חושד במשתנה הבוליאני אבל לא בטוח.

- - - תגובה אוחדה: - - -

טעות שלי, אתה צודק.

בכל מקרה, לא חסר לך שום שלב ביניים. רק קצת ניסיון. לומדים רק דרך האצבעות.

רצוי גם להשתמש בשמות משמעותיים למשתנים. קשה להבין מה זה s_prime ומה n_prime

עוד דבר:

else if (i<=1){
continue;
}
else

היה עדיף שאת הבלוק הגדול היית מכניס ב-else הראשון (אם i גדול מ-1) ואז אין לך שום else continue.

האם עדיף לקרוא למשתנים בשמות ארוכים יותר כמו number_of_prime שיש סכנה גדולה יותר לטעות בהם במהלך הקוד?

או שעדיף להשאיר n_prime ופשוט להסביר בהערה את הכוונה?

לגבי ההצעה של תיקון הקוד- החלפתי למה שהצעת. שאלה עקרונית- אם הייתי משאיר כמו שכתבתי, במה זה היה מתבטא במחשב? זמן הרצה ארוך יותר של התוכנית?

קישור לתוכן
שתף באתרים אחרים

  • תגובות 151
  • נוצר
  • תגובה אחרונה

יש לך 2 אפשרויות לדבג - או להוסיף הדפסות של הערכים, או להשתמש בדיבאגר המובנה ולעקוב אחרי המשתנים השונים.

לגבי תיקון הקוד - א. כן, מתבצעת פעולה נוספת של continue. ב. זה יותר קריא וברור, הקוד קצר יותר. גם מבחינה לוגית יותר פשוט להבין מה קורה כשמתקיים תנאי מסויים ולא להפך.

שמות משתנים - יותר מקובל להשתמש בשיטת ה-camleCase ככה שאתה כותב את המילים מחובר ומשתמש באות גדולה לכל מילה חדשה. למשל: numOfPrimes, buttonArray. שים לב שבאקליפס יש לך קיצור /+alt להשלמת מילים נפוצות

קישור לתוכן
שתף באתרים אחרים

אוקיי ביצעתי הדפסת ערכים אחרי כל עדכון של המשתנים.

כמו שחשבתי, יש איזושהי בעיה עם המשתנה הבוליאני שאני לא מצליח להבין.

הזנתי ערכים 2 ו 4. עבור 2 ו- 3 אין בעיה, התוכנית מזהה אותם כראשוניים והכל מודפס בסדר.

עבור הערך 4, משום מה המשתנה הבלואני prime נשאר על true ולכן מתבצע עדכון נוספת של המשתנים numOfPrimes ו sumOfPrimes ולכן הטעות בפלט.

הנה הקוד של התוכנית השוב (ההוראות להדפסה של המשתנים זמניות עד שאבין את הבעיה):


import java.util.Scanner;
public class Ex2 {


public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int x = s.nextInt();
int y = s.nextInt();
s.close();
int sumOfPrimes = 0;
int numOfPrimes = 0;
int first_prime = 2;
boolean prime;

for (int i=x; i<=y; i++){
if (i==first_prime){
sumOfPrimes = sumOfPrimes+i;
numOfPrimes++;
System.out.println(sumOfPrimes + "/" + numOfPrimes);
}
else if (i>1) {

for (int n=2; n<i; n++){
if (i%n!=0){
prime = true;
}
else
{
prime = false;
break;
}
}
if (prime=true){
sumOfPrimes = sumOfPrimes+i;
numOfPrimes++;
System.out.println(prime);
System.out.println(sumOfPrimes + "/" + numOfPrimes);
}
}
}

if (numOfPrimes>0){
double average = sumOfPrimes / (double)numOfPrimes;
System.out.println(average);
}
else
System.out.println("0");
}


}



זה הקטע קוד שככל הנראה לא פועל כמו שחשבתי:


else
{
prime = false;
break;
}

כנראה יש לי פה איזושהי טעות בסיסית שאני לא מבין.

קישור לתוכן
שתף באתרים אחרים

נכנס לשם, המשתנה הבוליאני אכן מתעדכן ל false אבל משום מה הוא חוזר אחר כך ל true ומעדכן את המשתנים.

הנה הפלט (עבור X=2 ו Y=4):

true

2/1

true

5/2

false

true

9/3

3.0

- - - תגובה אוחדה: - - -

עדכון: פתרתי את הבעיה. הייתי צריך לכתוב בתנאי של ה If שבודק אם המספר ראשוני- (prime) ולא (prime =true) וכמו כן צריך לאתחל את המשתנה הבוליאני ל true או false.

לצערי אני לא מצליח להבין למה ה if צריך להיות כתוב כך. הרי המשתנה הבוליאני אמור לקבל ערוך true או false ואז אם התנאי שווה ל true הוא היה צריך לבצע את שינוי המשתנים. אני לא מבין למה זה לא עבד?

ומדוע כשאני משנה את התנאי ב if לרק prime , אני חייב לאתחל את המשתנה בתחילת התוכנית? הרי הוא מקבל ערך תוך כדי הלולאה.

קישור לתוכן
שתף באתרים אחרים

יופי, מצאת את הבעייה :)

טעות נפוצה של מתחילים היא להשתמש באופרטור = בתור בדיקה אם x=y. בפועל, מדובר בהשמה - אתה הכנסת למשתנה prime את הערך true ולא בדקת אם הוא true.

הביטויים prime == true ו- prime שקולים מאחר והביטוי prime מחזיר ערך בוליאני. כמו כן, הביטוי prime == false שקול לביטוי prime!

קישור לתוכן
שתף באתרים אחרים

ואו, יצאתי אידיוט מוחלט. הקטע שאופרטור = משמש להצבה ו == משמש לשיוויון הוא מאוד מטעה. צריך ממש לשנות את צורת החשיבה.

ידעת מהתחלה שזאת הטעות ולא אמרת, אה? :)

סתם, צוחק :). הדרך שבה עזרתם לי למצוא את הבעיה מאוד תרמה לי בסופו של דבר, הבנתי שביצוע טבלת מעקב והדפסת משתנים (דברים שלא חשבתי עליהם קודם) עוזרת מאוד בלהבין איך התוכנית עובדת וכך גם למצוא את התקלה.

דרך אגב, עדיין לא הבנתי מדוע צריך לאתחל את prime בתחילת התוכנית. הרי הוא מקבל ערך תוך כדי הלולאה, אז בשביל מה? אם הוא לא מאותחל, התוכנית לא מתקמפלת.

קישור לתוכן
שתף באתרים אחרים

כל טיפוס מקבל ערך דיפולטיבי באם הוא לא מאותחל. בוליאן למשל מאותחל ל-false. זו אינה שגיאת קומפילציה.

בכל מקרה זה good practice לאתחל משתנים. מה אם הלולאה לא מתבצעת בכלל?

קישור לתוכן
שתף באתרים אחרים

כל טיפוס מקבל ערך דיפולטיבי באם הוא לא מאותחל. בוליאן למשל מאותחל ל-false. זו אינה שגיאת קומפילציה.

בכל מקרה זה good practice לאתחל משתנים. מה אם הלולאה לא מתבצעת בכלל?

לא ירדתי לסוף דעתך. אם בוליאן מאותחל בדיפולט ל false, מדוע הוא נותן לי שגיאה כשאני לא מאתחל אותו?

קישור לתוכן
שתף באתרים אחרים

רק שדות של מחלקות מאותחלים אוטומטית. משתנים פנימיים של פונקציות אתה חייב לאתחל בעצמך, אחרת הקומפיילר יתן שגיאה.

אבל המשתנה מקבל ערך בהמשך הפונקציה.

כבר השתמשתי במשתנים שלא אתחלתי אותם אלא רק הצהרתי, והם אחר כך קיבלו ערכים והכל היה בסדר.

אני לא מבין למה במקרה הספציפי הזה הוא לא נותן לי.

סתם דוגמה במקרה הספציפי בתוכנית שלי- אני הצהרתי ונתתי ערך ל double average רק בסוף התוכנית.

באותה מידה יכולתי רק להצהיר על average בתחילת התוכנית, ובסופה לתת את הערך. על זה הוא לא נותן לי שגיאה.

אם כך, מדוע זה לא עובד באותה צורה עם המשתנה הבוליאני שהצהרתי?

- - - תגובה אוחדה: - - -

עדכון: נראה לי שהבנתי.

במידה והלולאה לא מתקיימת, הערך הבוליאני שלי לא מקבל ערך. זאת הסיבה שאני צריך לאתחל אותו (אף על פי שאני בכלל לא עושה בו שימוש אם הלולאה לא מתקיימת).

האם אני צודק?

קישור לתוכן
שתף באתרים אחרים

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.


×
  • צור חדש...