מבוא לתכנות ב- JAVA תרגול 12
מספרים גדולים במהלך הקורס ראינו את הטיפוס long לייצוג מספרים שלמים גדולים יותר מאשר.int אולם, ייצוג זה מוגבל ולא מאפשר לייצג מספרים בני 20 ספרות ומעלה. אחת השיטות לממש מספרים שלמים גדולים עם מספר ספרות שאינו מוגבל היא בעזרת רשימות מקושרות. למשל המספר 49867349855739457385646546945 ניתן לייצוג באופן הבא: 4 9 8... 5 null
מספרים גדולים כתבו שיטה רקורסיבית המקבלת שני מספרים גדולים המיוצגים ע"י רשימות. הפונקציה תקבל את הקודקוד הראשון מכל רשימה ותחזיר כפלט: 1 אם המספר הראשון גדול מהמספר השני (1-) אם המספר הראשון קטן מהמספר השני 0 אם המספרים שווים ניתן להניח ששני המספרים הם מאותו אורך public static int comparebignumbers(node<integer> n1, Node<Integer> n2) n1 5 n2 9 8... 5 null 5 7 4... 2 null
השוואת מספרים גדולים public static int comparebignumbers(node<integer> n1, Node<Integer> n2){ if (n1 == null && n2 == null){ return 0; if (n1.getdata() < n2.getdata()){ return -1; if (n1.getdata() > n2.getdata()){ return 1; return comparebignumbers(n1.getnext(), n2.getnext());
השוואת מספרים גדולים public static int comparebignumbers(node<integer> n1, Node<Integer> n2){ if (n1 == null && n2 == null){ return 0; if (n1.getdata() < n2.getdata()){ return -1; if (n1.getdata() > n2.getdata()){ return 1; return comparebignumbers(n1.getnext(), n2.getnext());
פולינום לפניך המחלקה Term שמייצגת איבר בפולינום public class Term { private int coef; private int degree; public Term(int coef, int degree){ this.coef = coef; this.degree = degree; Getters and setters
פולינום ניתן לייצג פולינום ע"י רשימה מקושרת באופן הבא: כל איבר ברשימה מטיפוס Term שומר מקדם בשדה coef ומעריך בשדה.degree איברי הפולינום מסודרים בסדר יורד לפי המעריך כאשר המעריך הגדול מופיע בראש הרשימה. כל מעריך מופיע ברשימה לכל היותר פעם אחת. למשל הפולינום 5x 4 + 3x 7 + 6 מיוצג ע"י הרשימה 3 7 5 4 6 0 null public static List<Term> add(list<term> pol1, List<Term> pol2) כתבו את השיטה: המקבלת 2 פולינומים ומחזירה את הפולינום המתקבל ע"י חיבור 2 הפולינומים
חיבור פולינומים public static List<Term> add(list<term> pol1, List<Term> pol2){ List<Term> res = new List<Term>(); Node<Term> p1 = pol1.getfirst(); Node<Term> p2 = pol2.getfirst(); Node<Term> p3 = res.getfirst(); נתקדם עד אשר סיימנו לסרוק לפחות את אחד הפולינומים while(p1!= null && p2!= null){ if (p1.getdata().getdegree() > p2.getdata().getdegree()){ p3 = res.insert(p3, p1.getdata()); p1 = p1.getnext(); else if (p1.getdata().getdegree() < p2.getdata().getdegree()){ p3 = res.insert(p3, p2.getdata()); p2 = p2.getnext(); else{ while(p1!= null){ p3 = res.insert(p3, p1.getdata()); p1 = p1.getnext(); while(p2!= null){ return res; איך נתייחס כאשר מעריך הראשון גדול מהשני בהתאמת אינדקסים ולהיפך? Term t = new Term(p1.getData().getCoeff() + p2.getdata().getcoeff(), p1.getdata().getdegree()); p3 = res.insert(p3, t); וכשהמעריכים שווים בהתאמת אינדקסים? p1 = p1.getnext(); p2 = p2.getnext(); אולי משהו נשאר? p3 = res.insert(p3, p2.getdata()); p2 = p2.getnext();
חיבור פולינומים public static List<Term> add(list<term> pol1, List<Term> pol2){ List<Term> res = new List<Term>(); Node<Term> p1 = pol1.getfirst(); Node<Term> p2 = pol2.getfirst(); Node<Term> p3 = res.getfirst(); נתקדם עד אשר סיימנו לסרוק לפחות את אחד הפולינומים while(p1!= null && p2!= null){ if (p1.getdata().getdegree() > p2.getdata().getdegree()){ p3 = res.insert(p3, p1.getdata()); p1 = p1.getnext(); else if (p1.getdata().getdegree() < p2.getdata().getdegree()){ p3 = res.insert(p3, p2.getdata()); p2 = p2.getnext(); else{ Term t = new Term(p1.getData().getCoeff() + p2.getdata().getcoeff(), p1.getdata().getdegree()); p3 = res.insert(p3, t); p1 = p1.getnext(); p2 = p2.getnext(); while(p1!= null){ p3 = res.insert(p3, p1.getdata()); p1 = p1.getnext(); while(p2!= null){ p3 = res.insert(p3, p2.getdata()); p2 = p2.getnext(); return res;
תרגיל: מציאת האיבר שמופיע הכי הרבה ברשימה ממשו את הפונקציה maxoccelement המקבלת רשימה של מספרים ומחזירה את המספר שמופיע הכי הרבה פעמים ברשימה public static Integer maxoccelement(list<integer> ls){ רעיון? נספור עבור כל מופע כמה פעמים הוא מופיע ברשימה וכך נדע מי המקסימלי טיפ כדאי לרשום פונקציית עזר שמקבלת את הרשימה ומספר ובודקת כמה פעמים הוא מופיע ברשימה 1 2 1 3 null האיבר שמופיע הכי הרבה הוא 1
נתחיל בכתיבת פונקציית עזר public static int countocc(list<integer> ls, Integer val){ int ans = 0; if (ls == null){ return 0; for (Node<Integer> p = ls.getfirst(); p!= null; p = p.getnext()){ if (p.getdata().equals(val)){ ans++; return ans;
פתרון public static Integer maxoccelement(list<integer> ls){ if (ls == null ls.isempty()){ return null; int maxocc = countocc(ls, ls.getfirst().getdata()); Integer element = ls.getfirst().getdata(); נחזיק p.getnext()){ משתנה= p עזר null; שיהיה =! שווהp למספר המופעים ls.getfirst(); של= p האיבר הראשון (Node<Integer> ומצביע אליו for int temp = countocc(ls, במשתנה עזר נוסף p.getdata()); נבדוק את מופעי כל השאר ונשווה למקסימלי בכל עת. temp){ אם> נמצא גדול if (maxocc ממנו, maxocc = temp; המצביע שיכוון אל הגדול. element = p.getdata(); נחליף את return element;
פתרון public static Integer maxoccelement(list<integer> ls){ if (ls == null ls.isempty()){ return null; int maxocc = countocc(ls, ls.getfirst().getdata()); Integer element = ls.getfirst().getdata(); for (Node<Integer> p = ls.getfirst(); p!= null; p = p.getnext()){ int temp = countocc(ls, p.getdata()); if (maxocc < temp){ maxocc = temp; element = p.getdata(); return element;
תרגיל: הסרת כפילויות ברשימה ממשו את הפונקציה removeduplicates שבהינתן רשימה מסירה את כל המופעים הכפולים של איברים ברשימה כך שבסיום הפעולה כל איבר ברשימה יופיע בדיוק פעם אחת public static void removeduplicates(list<integer> ls){ רעיון? 2 מצביעים, 2 לולאות )מקוננות( עבור כל איבר שפוגשים נבדוק הלאה ממנו האם יש זהה לו, אם כן נעיף אותו!
פתרון: הסרת כפילויות ברשימה public static void removeduplicates(list<integer> ls){ if (ls == null){ return; for (Node<Integer> p = ls.getfirst(); p!= null; p = p.getnext()){ Node<Integer> q = p.getnext(); while (q!= null){ if (p.getdata().equals(q.getdata())){ q = ls.remove(q); else{ q = q.getnext();
תרגיל: הפרש בין 2 רשימות ממשו את הפונקציה listsminus המקבלת 2 רשימות ls1,ls2 ומחזירה רשימה שאיבריה הם כל האיברים מהרשימה ls1 שאינם מופיעים בls2 public static List<Integer> listsminus(list<integer> ls1, List<Integer> ls2){...
תרגיל: הפרש בין 2 רשימות ממשו את הפונקציה listsminus המקבלת 2 רשימות ls1,ls2 ומחזירה רשימה שאיבריה הם כל האיברים מהרשימה ls1 שאינם מופיעים בls2 public static List<Integer> listsminus(list<integer> ls1, List<Integer> ls2){... private static boolean contains(list<integer> ls, Integer data) { for (Node<Integer> p = ls.getfirst(); p!= null; p = p.getnext()){ if (p.getdata().equals(data)){ return true; return false; פונקציית עזר שמקבלת רשימה ומספר ובודקת אם הוא קיים ברשימה
פתרון public static List<Integer> listsminus(list<integer> ls1, List<Integer> ls2){ List<Integer> ans = new List<Integer>(); Node<Integer> pos = null; for (Node<Integer> p = ls1.getfirst(); p!= null; p = p.getnext()){ p.getdata())){ עזר לרוץ על הרשימה (!contains(ls2, if הראשונה. נגדיר מצביע לרשימה חדשה אותו נחזיר ומצביע pos = ans.insert(pos, p.getdata()); נממש קוד שרץ על הרשימה הראשונה ובודק עבור כל איבר אם הוא קיים ברשימה השניה, אם לא נוסיף אותו לרשימה החדשה. איך נבדוק? באמצעות פונקצית העזר שיממשנו בשקופית הקודמת ומופיעה גם פה מטה return ans; private static boolean contains(list<integer> ls, Integer data) { for (Node<Integer> p = ls.getfirst(); p!= null; p = p.getnext()){ if (p.getdata().equals(data)){ return true; return false;
פתרון public static List<Integer> listsminus(list<integer> ls1, List<Integer> ls2){ List<Integer> ans = new List<Integer>(); Node<Integer> pos = null; for (Node<Integer> p = ls1.getfirst(); p!= null; p = p.getnext()){ if (!contains(ls2, p.getdata())){ pos = ans.insert(pos, p.getdata()); return ans; private static boolean contains(list<integer> ls, Integer data) { for (Node<Integer> p = ls.getfirst(); p!= null; p = p.getnext()){ if (p.getdata().equals(data)){ return true; return false;