[Powered by Google Translate] [Walkthrough - סט בעיה 6]
[Zamyla צ'אן - אוניברסיטת הרווארד]
[זה CS50. - CS50.TV]
>> שלום לכולם, וברוך הבאים לWalkthrough 6: פאף Huff'n.
בפאף Huff'n מה שאנחנו עושים הוא הולך להיות התמודדות עם קובץ דחוס האפמן
ולאחר מכן מנפח אותו בחזרה למעלה, ולכן decompressing,
כדי שנוכל לתרגם מ0s ו 1s שהמשתמש שולח לנו
ולהמיר אותו בחזרה לטקסט המקורי.
Pset 6 הולכים להיות די מגניב כי אתה הולך לראות כמה מהכלים
שבו השתמש בpset 4 ו 5 וpset סוג של שילובם בקונספט די מגניב 1
כשאתה בא לחשוב על זה.
>> כמו כן, ניתן לטעון, pset 4 ו 5 היה psets המאתגר ביותר שהיו לנו להציע.
אז מעכשיו, יש לנו 1 יותר pset זה ב-C,
ואז אחרי שאנחנו בתכנות אינטרנט.
אז לברך את עצמכם להשגה על הדבשת הקשה ביותר בCS50.
>> העברה ב לפאף Huff'n, ארגז הכלים שלנו לpset זה הולך להיות עצי האפמן,
לכן הבנה לא רק במיוחד עצי האפמן אופן עבודה של עצים בינארי אלא גם,
איך הם בנויים.
ואז אנחנו הולכים להיות הרבה קוד הפצה בpset זה,
ואנחנו נבוא לראות שבעצם חלק מהקוד
אנחנו אולי לא יכולים להבין באופן מלא עדיין,
ולכן אלה יהיו. את קבצי C, אבל אז. הקבצים המצורפים h
ייתן לנו מספיק הבנה שאנו זקוקים לכך שאנחנו יודעים איך פונקציות אלו עובדות
או לפחות את מה שהם אמורים לעשות - התשומות והתפוקות שלהם -
גם אם אנחנו לא יודעים מה קורים בקופסה השחורה
או שאינך מבין מה קורה בקופסה השחורה שבפנים.
ולבסוף, כרגיל, אנו עוסקים במבני נתונים חדשים,
סוגים מסוימים של צומת המצביעים על דברים מסוימים,
וכן כאן יש עט ונייר לא רק לתהליך העיצוב
וכשאתה מנסה להבין איך pset צריכה לעבוד
אלא גם בניפוי.
אתה יכול לקבל GDB צד העט והנייר שלך בזמן שאתה לוקח את מה שהערכים הם,
שם החיצים שלך מצביעים, ודברים כאלה.
>> ראשית בואו נסתכל על עצי האפמן.
עצי האפמן הם עצים בינאריים, כלומר כל צומת יש 2 ילדים בלבד.
בעצי האפמן האופייני הוא שהערכים השכיחים ביותר
מיוצגים על ידי את הביטים הכי מעט.
ראינו בדוגמאות הרצאה של קוד מורס, סוג של מאוחד שכמה מכתבים.
אם אתה מנסה לתרגם או דואר, למשל,
אתה מתרגם את זה לעתים קרובות, כך שבמקום שיצטרך להשתמש בסט המלא של ביטים
הוקצה עבור אותו סוג הנתונים רגיל, אתם דוחסים אותו למעט יותר,
ואז אותיות אלה המיוצגים בתדירות נמוכה יותר מיוצגות עם חתיכות ארוכות יותר
כי אתה יכול להרשות לעצמך שכשאתה שוקל את התדרים שהמכתבים האלה מופיעים.
יש לנו את אותו רעיון כאן בעצי האפמן
שבו אנו עושים את שרשרת, סוג של הדרך להגיע לתווים המסוימים.
ולאחר מכן את הדמויות שיש להם רוב בתדר
הולכים להיות מיוצגים עם חתיכות הקטנות ביותר.
>> אופן שבו אתה לבנות עץ האפמן
היא על ידי נחת את כל הדמויות המופיעות בטקסט
וחישוב התדר שלהם, באיזו תדירות הם מופיעים.
זה יכול להיות או לספור כמה פעמים מופיעות אותיות אלה
או אולי אחוז מתוך כל הדמויות כמה כל אחד מהם מופיע.
ואז מה שאתה עושה הוא ברגע שאתה צריך את כל זה החוצה מיפה,
אז אתה מחפש את 2 תדרים הנמוכים ולאחר מכן תצטרף אליהם כאחים
אז שבו צומת האב יש תדר שהוא הסכום של 2 ילדיה.
ואז אתה אומר שעל ידי כינוס הצומת השמאלית,
אתה מבין שעל ידי ביצוע 0 הסניף,
ולאחר מכן את הצומת הימנית ביותר היא הענף 1.
כפי שראינו בקוד מורס, האחד תפס אותך היה שאם היה לך רק צפצוף והצפצוף
זה היה מעורפל.
זה יכול גם להיות מכתב 1 או שזה יכול להיות רצף של 2 אותיות.
אז מה עושה עצי האפמן הוא, כי על ידי אופיין של הדמויות
או הדמויות שלנו סופיות בפועל מהווים את צומת האחרונים בענף -
אנו מתייחסים לאלו כעלים - מכוח שיש לא יכול להיות כל עמימות
במונחים של מכתב שאתה מנסה לקודד עם הסדרה של ביטים
כי בשום מקום לאורך הביטים המייצגים את מכתב 1
יהיה לך להיתקל במכתב אחר שלם, ולא יהיה כל בלבול ש.
אבל תלכו לדוגמאות שאתם ממש יכולים לראות כי
במקומנו רק אומר לך שזה נכון.
>> בואו נסתכל על דוגמה פשוטה לעץ האפמן.
יש לי כאן שהיא מחרוזת ארוכה 12 תווים.
יש לי 4 כ, 6 ארוחת בוקר, ו 2 Cs.
הצעד הראשון שלי יהיה לספור.
כמה פעמים לא מופיע? נראה 4 פעמים במחרוזת.
B מופיע 6 פעמים, ו-C מופיע 2 פעמים.
באופן טבעי, אני הולך להגיד אני משתמש ב 'לרוב,
אז אני רוצה לייצג B עם המספר הנמוך ביותר של ביטים, מספר הנמוך ביותר של 0s ו 1s.
ואז אני גם הולך לצפות C לדרוש את הכמות הגדולה ביותר של 0s ו 1s גם כן.
ראשית מה שעשיתי כאן הוא שהנחתי אותן בסדר עולה מבחינת תדירות.
אנו רואים שC ו, אלה הם 2 התדרים הנמוכים ביותר שלנו.
אנו יוצרים צומת אב, וכי צומת ההורה לא צריך מכתב הקשור אליו,
אבל יש תדר, שהוא הסכום.
הסכום הופך 2 + 4, שעומדים על 6.
אז אנחנו עוקבים אחרי הענף השמאלי.
אם אנחנו נמצאים בצומת 6, אז הייתי לעקוב 0 להגיע לג
ואז 1 להגיע לא
אז עכשיו יש לנו 2 צמתים.
יש לנו את הערך 6 ואז יש לנו גם צומת אחר עם הערך 6.
ולכן אלה 2 הם לא רק 2 הנמוכים ביותר, אלא גם בדיוק 2 שעזבו,
אז אנחנו מצטרפים לאלה של הורה אחר, עם הסכום להיות 12.
אז הנה יש לנו עץ האפמן
איפה ניתן לקבל ל-B, שהיה אמור להיות רק 1 הביט
ולאחר מכן להגיע ליהיה לנו 01 ולאחר מכן יש C 00.
אז הנה אנו רואים שבעצם אנחנו מייצגים את התווים האלה עם 1 או 2 ביטים
בי B, כצפוי, יש לפחות.
ואז ציפינו C יש רוב, אך מכיוון שזה עץ האפמן קטן כזה,
אז גם הוא מיוצג על ידי 2 ביטים בניגוד לאי שם באמצע.
>> רק לעבור על דוגמה פשוטה אחרת של עץ האפמן,
אומר שיש לך את המחרוזת "שלום".
מה שאתה עושה הוא ראשון שהייתי אומר כמה פעמים אין H מופיע בזה?
H מופיע פעם אחת ולאחר מכן דואר מופיע פעם אחת ולאחר מכן יש לנו אני מופיע פעמים
o ומופיעה פעם אחת.
ואם כך אנו מצפים שמכתב להיות מיוצגים על ידי המספר המינימאלי של ביטים?
[תלמיד] l. אני. >> Yeah. l הוא נכון.
אנו מצפים l להיות מיוצגים על ידי המספר המינימאלי של ביטים
כי אני משמש ביותר במחרוזת "שלום".
מה שאני הולך לעשות עכשיו הוא למשוך את ההקשרים האלה.
יש לי 1, שהוא גובה, ולאחר מכן עוד 1, שהוא הדואר, ולאחר מכן 1, אשר הוא O -
עכשיו אני מכניס אותם במטרה - ולאחר מכן 2, שהוא אני.
אז אני אומר שהדרך שאני לבנות עץ האפמן היא למצוא את 2 צומת עם התדרים הפחות
ולהפוך אותם לאחים על ידי יצירת צומת אב.
כאן יש לנו 3 צומת עם התדירות הנמוכה ביותר. הם כולם 1.
אז הנה אנחנו בוחרים בו אנחנו הולכים קישור הראשון.
נניח שאני בוחר H והדואר.
הסכום של 1 + 1 הוא 2, אבל הצומת הזה אין מכתב המשויך אליו.
זה פשוט מחזיק את הערך.
עכשיו אנחנו מסתכלים על 2 תדרים הקרובים הנמוכים ביותר.
זה 2 ו 1. זה יכול להיות אחד מאלה 2, אבל אני הולך לבחור אחד זה.
הסכום הוא 3.
ולבסוף, יש לי רק 2 שמאל, אז זה הופך להיות 5.
אז הנה, כצפוי, אם אני ממלא בקידוד בשביל זה,
1s תמיד הסניף ו0s ימין הוא השמאל.
אז יש לנו אני מיוצג על ידי רק קצת 1 ולאחר מכן o על ידי 2
ולאחר מכן על ידי הדואר 2 ולאחר מכן H נופל ל3 חתיכות.
אז אתה יכול להעביר את המסר הזה "שלום" במקום באמת משתמש בתווים
רק על ידי 0s ו 1s.
עם זאת, זכור כי בכמה מקרים שהיו לנו קשרים עם התדר שלנו.
יכולנו הצטרפנו גם H וo 1 אולי.
או אז בשלב מאוחר יותר, כאשר היו לנו אני מיוצג על ידי 2
כמו גם הצטרפתי לאחד מיוצג על ידי 2, היינו יכול קשור אחת מהן.
>> וכך, כאשר אתה שולח 0s ו 1s, שלמעשה אינו מבטיח
שהנמען יכול לקרוא את ההודעה שלך במלואו מייד את הבת
משום שהם אולי לא יודעים שהחלטה שקבלת.
לכן, כאשר יש לנו עסק עם דחיסת האפמן,
איכשהו יש לנו לספר לנמען ההודעה שלנו איך אנחנו החלטנו -
הם צריכים לדעת איזה מידע נוסף
בנוסף להודעה הדחוסה.
הם צריכים להבין מה באמת נראה כמו העץ,
איך אנחנו בעצם קבלנו את ההחלטות האלה.
>> כאן פשוט עשו דוגמאות המבוססות על הספירה בפועל,
אבל לפעמים אתה יכול להיות גם עץ האפמן
בהתבסס על התדירות שבה מופיעות אותיות, וזה אותו התהליך המדויק.
כאן אני מביע אותה במונחים של אחוז או שברים,
וכן כאן בדיוק את אותו דבר.
אני מוצא את 2 נמוך ביותר, תסכם אותם, 2 הבאים הנמוכים, תסכמו אותם,
עד שיש לי עץ מלא.
למרות שאנחנו יכולים לעשות את זה כך או כך, כאשר יש לנו עסק עם אחוזים,
זה אומר שאנחנו מחלקים דברים והתמודדות עם נקודות עשרוניות או לייתר דיוק צף
אם אנחנו חושבים על מבני נתונים של ראש.
מה אנחנו יודעים על צף?
מה בעיה נפוצה כאשר יש לנו עסק עם מצופים?
[תלמיד] חשבון לא מדויק. >> כן. חוסר דיוק.
בגלל חוסר דיוק נקודה צפה, לpset זה כך שאנו מוודאים
כי אנחנו לא לאבד את כל ערכים, אז אנחנו למעשה הולכים להיות התמודדות עם הספירה.
אז אם הייתם חושב על צומת האפמן, אם אתה מסתכל אחורה למבנה כאן,
אם אתה מסתכל בירוקים יש תדר הקשור אליו
כמו גם שהוא מצביע לצומת לשמאלו, כמו גם צומת לזכותה.
ולאחר מכן את אלה האדומים יש גם דמות שקשורה אליהן.
אנחנו לא הולכים לעשות פרחים נפרדים להורים ואז הבלוטות הסופיות,
בו אנו מתייחסים אליו כעלים, אלא אלה יהיו רק צריכים ערכי NULL.
לכל צומת שנהיה לנו אופי, שסמל שמייצגת צומת,
אז תדירות כמו גם מצביע לילד השמאלי שלו, כמו גם זכותה הילד.
העלים, שהם בתחתית, היה צריכים גם מצביעי צומת
לשמאלם ומימינם, אבל מכיוון שערכים אלה אינם מצביעים על בלוטות בפועל,
מה הערך שלהם יהיה? >> [תלמיד] NULL. NULL. >> בדיוק.
הנה דוגמה לאופן שעשוי לייצג את התדירות בצפים,
אבל אנחנו הולכים להיות התמודדות עימו עם שלמים,
אז כל מה שעשיתי הוא לשנות את סוג הנתונים שיש.
>> בואו נלך על קצת יותר מדוגמה מורכבת.
אבל עכשיו שעשינו את אלה פשוטים, זה רק את אותו התהליך.
אתה מוצא את 2 תדרים הנמוכים, לסכם את התדרים
וזה התדר החדש של צומת אביך,
אשר לאחר מכן מצביע לשמאלו עם 0 סניף והנכון עם הסניף 1.
אם יש לנו את המחרוזת "זה cs50," אז אנחנו לספור כמה פעמים מוזכרים T,
ח ציין, אני, ס, צ, 5, 0.
אז מה שעשיתי כאן הוא עם הבלוטות האדומות אני רק ניטעתי,
אני אמרתי שאני הולך לעשות בתווים אלה סופו של דבר בתחתית העץ שלי.
מי הולך להיות כל העלים.
אז מה שעשיתי הוא שמיינתי אותם לפי תדירות בסדר עולה,
וזה בעצם אופן שבו קוד pset עושה את זה
הוא הוא ממיין אותו על ידי תדר ואז לפי סדר אלפביתי.
אז יש לו את המספרים ראשונים ולאחר מכן לפי סדר אלפביתי של התדר.
ואז מה הייתי עושה הוא הייתי מוצא 2 הנמוך ביותר. זה 0 ו 5.
אני היית מסכם אותם, וזה 2. ואז הייתי ממשיך, למצוא 2 הבאים הנמוך יותר.
אלה הם 1s 2, ולאחר מכן אלו הפכו 2 גם כן.
עכשיו אני יודע שהשלב הבא שלי הולך להיות שהצטרף המספר הנמוך ביותר,
שהוא T, 1, ולאחר מכן בחירה באחת מהבלוטות שיש 2 כתדר.
אז הנה יש לנו 3 אפשרויות.
מה שאני הולך לעשות לשקופית רק בראייתו לארגן מחדש אותם בשבילך
כך שאתה יכול לראות איך אני בונה אותו.
מה הקוד וקוד ההפצה שלך הולך לעשות יהיה להצטרף 1 T
בצומת 0 ו 5.
אז שסכומים עד 3, ולאחר מכן אנו ממשיכים בתהליך.
2 ו 2 עכשיו הם הנמוכים ביותר, אז אלה הסכום עד 4.
כולם לאחר כל כך הרבה? אוקיי.
ואז אחרי שיש לנו 3 ו 3 שיש להוסיף עד,
אז שוב אני רק מיתוג זה, כך שאתה יכול לראות חזותי, כך שהוא לא מקבל יותר מדי מבולגן.
אז יש לנו 6, ולאחר מכן הצעד הסופי שלנו הוא שעכשיו יש לנו רק 2 צמתים
נסכם אלה כדי להפוך את השורש של העץ שלנו, שהוא 10.
והמספר 10 הגיוני כי כל צומת מיוצג,
ערכם, מספר התדר שלהם, היה כמה פעמים הם הופיעו במחרוזת,
ולאחר מכן יש לנו 5 תווים במחרוזת שלנו, כך שזה הגיוני.
אם אנחנו מסתכלים על איך הייתי לקודד אותו ממש,
כצפוי, אני והים, המופיע בתדירות הגבוהה ביותר
מיוצגים על ידי המספר הנמוך ביותר של ביטים.
>> היזהר כאן.
בעצי האפמן המקרה ממש חשוב.
אותיות רישיות S הוא שונה משל אותיות קטנות.
אם היו לנו "זה CS50" עם אותיות גדולות, ולאחר מכן של האותיות הקטנות היה מופיע רק פעמים,
יהיה צומת עם 2 כערכו, ולאחר מכן אותיות רישיות S תהיינה רק פעם אחת.
אז העץ שלך ישנה את מבנים, כי אתה באמת צריך עלה נוסף כאן.
אבל הסכום עדיין יהיה 10.
זה מה שאנחנו באמת הולכים להתקשר אל הבדיקה,
בנוסף לכל סעיפים.
>> עכשיו שאנחנו כבר מכוסים עצי האפמן, אנחנו יכולים לצלול לתוך פאף Huff'n, pset.
אנחנו עומדים להתחיל עם קטע של שאלות,
וזה הולך להביא לך רגיל עם עצים בינאריים וכיצד פועל סביב זה:
בלוטות לציור, יצירת struct typedef שלך לצומת,
ולראות איך אתה יכול להכניס לתוך עץ בינארי, שסדר,
חוצה אותו, ודברים כאלה.
ידע שבהחלט הולך לעזור לך כאשר אתה צולל לתוך חלק פאף Huff'n
של pset.
במהדורה הסטנדרטית של pset, המשימה שלך היא ליישם פאף,
ובגרסת האקר המשימה שלך היא ליישם הף.
מה הף עושה זה לוקח טקסט ואז זה מתרגם אותו ל0s ו 1s,
לכן התהליך שעשינו לעיל שבו אנו סופרים את התדרים
ואז עשה את העץ ואז אמר, "איך אני מקבל T?"
T מיוצג על ידי 100, דברים כאלה,
ואז הף ייקח את הטקסט ואז הפלט שבינארי.
אבל גם בגלל שאנחנו יודעים שאנחנו רוצים לאפשר לנמען ההודעה שלנו
כדי לשחזר את אותו עץ בדיוק, זה כולל גם מידע על ספירת השכיחות.
אז עם פאף אנו מקבלים קובץ בינארי של 0s ו 1s
ונתן גם מידע על התדרים.
אנו מתרגמים את כל אלו שיחזרו 0s ו 1s להודעה המקורית שהייתה,
לכן אנחנו decompressing ש.
אם אתה עושה את המהדורה הרגילה, אתה לא צריך ליישם הף,
ואז אתה יכול פשוט להשתמש ביישום צוות של הף.
יש הוראות במפרט על איך לעשות את זה.
אתה יכול להפעיל את יישום צוות של הף על קובץ טקסט מסוים
ולאחר מכן להשתמש בפלט שכקלט לפאף.
>> כפי שציינתי קודם, יש לנו הרבה קוד חלוקה לזה.
אני מתכוון להתחיל ללכת דרכו.
אני הולך לבלות את רוב הזמן ב. קבצי h
כי ב. את קבצי C, כי יש לנו. h
ושמספק לנו את אבות הטיפוס של הפונקציות,
אנחנו לא צריכים באופן מלא כדי להבין בדיוק -
אם אתה לא מבין מה קורה ב. את קבצי C, אז אל תדאגו יותר מדי,
אבל בהחלט תנסה להעיף מבט, כי זה עלול לתת כמה רמזים
וזה שימושי להתרגל לקריאת הקוד של אנשים אחרים.
>> כאשר מסתכלים על huffile.h, בהערותיו מצהירות שכבת ההפשטה לקבצי האפמן מקודדים.
אם אנחנו הולכים למטה, אנחנו רואים שיש מקסימום של 256 סמלים שאולי צריך קודים ל.
זה כולל את כל האותיות אלף - הגדולות וקטנות -
ואז סמלים ומספרים, וכו '
אז כאן יש לנו מספר קסם זיהוי קובץ האפמן מקודד.
בתוך קוד האפמן שהם הולכים להיות מספר קסם מסוים
קשור עם הכותרת.
זה אולי נראה כמו סתם מספר קסם אקראי,
אבל אם אתה באמת לתרגם אותה לASCII, אז זה בעצם מפרט את הף.
כאן יש לנו struct לקובץ האפמן בקידוד.
יש כל המאפיינים הללו קשורים קובץ הף.
אז כאן יש לנו את הכותרת לקובץ הף, ולכן אנחנו קוראים לזה Huffeader
במקום להוסיף שעות נוספות בגלל שזה נשמע אותו דבר בכל מקרה.
חמוד.
יש לנו מספר קסם המשויך אליו.
אם זה קובץ הף בפועל, זה הולך להיות המספר למעלה, זה קסם.
ואז זה יהיה מערך.
אז לכל סמל, שבה יש 256,
זה הולך לרשום את כל מה התדירות של הסמלים האלה הן בתוך קובץ הף.
ולבסוף, יש לנו את בדיקה עבור התדרים,
שאמור להיות בסכום של תדרים אלה.
אז זה מה שHuffeader הוא.
אז יש לנו כמה פונקציות שמחזירות את הקטע הבא בקובץ הף
כמו גם כותב קצת לקובץ הף, ואז זה פונקציה כאן, hfclose,
שבעצם סוגר את קובץ הף.
לפני כן, היינו לנו עסק עם ישר פשוט fclose,
אבל כאשר יש לך קובץ הף, במקום fclosing זה
מה אתה בעצם הולך לעשות הוא hfclose וhfopen.
אלה הם פונקציות ספציפיות לקבצי הף שאנחנו הולכים להיות התמודדות עם.
אז הנה אנחנו קוראים בכותרת ואז לכתוב את הכותרת.
>> רק על ידי קריאה. קובץ h שאנחנו יכולים לקבל סוג של תחושה של מה קובץ הף יכול להיות,
מה מאפיינים יש לו, מבלי להיכנס ממש לתוך huffile.c,
אשר, אם לקפוץ למים, הולך להיות קצת יותר מורכב.
יש לו כל קובץ הקלט / פלט כאן התמודדות עם מצביעים.
כאן אנו רואים שכאשר אנו קוראים hfread, למשל, הוא עדיין מתמודד עם fread.
אנחנו לא להיפטר מהפונקציות הללו לחלוטין, אבל אנחנו שולחים את אלה שטופלו
בתוך קובץ הף במקום לעשות את כל זה בעצמנו.
אתה יכול להרגיש חופשי לסריקה דרך זה אם אתה סקרן
ותלך, ולקלף את השכבה קצת לאחור.
>> הקובץ הבא שאנחנו הולכים להסתכל הוא tree.h.
לפני בWalkthrough מחליק אמרנו שאנחנו מצפים האפמן צומת
ועשינו צומת struct typedef.
אנו מצפים שנהיה לו סמל, תדירות, ואז 2 כוכבי צומת.
במקרה זה מה שאנחנו עושים הוא שזה בעצם אותו הדבר
אלא שבמקום צומת אנחנו הולכים לקרוא להם עצים.
יש לנו פונקציה שכאשר אתה קורא להפוך עץ זה מחזיר אותך מצביע עץ.
בחזרה למאית, כשאתה היה עושה צומת חדש
אתה אמרת צומת * מילה חדשה = malloc (sizeof) ודברים כאלה.
בעיקרון, mktree הולך להיות התמודדות עם זה בשבילך.
בדומה לכך, כאשר ברצונך להסיר את עץ,
כך שבעצם הוא משחרר את העץ כשתסיים עם זה,
במקום לקרוא במפורש חופשי על זה, אתם למעשה רק הולכים להשתמש בפונקצית rmtree
שבו אתה עובר במצביע כדי שעץ ולאחר מכן tree.c יטפל בזה בשבילך.
>> אנו מצפים לtree.c.
אנו מצפים את אותן פונקציות חוץ מאשר לראות את היישום גם כן.
כפי שציפינו, כאשר אתה קורא את זה mktree mallocs גודלו של עץ למצביע,
מאתחל את כל הערכים לערך NULL, כך 0s או ערכי null,
ולאחר מכן מחזיר את המצביע לעץ הזה שיש לך רק malloc'd אליך.
הנה כאשר אתה קורא להסיר עץ זה גורם תחילה ודא כי אתה לא משחרר כפול.
היא מוודא כי למעשה יש לכם עץ שברצונך להסיר.
הנה כי עץ כולל גם את ילדיה,
מה זה עושה זה רקורסיבי קורא להסיר עץ בצומת השמאלית של העץ
כמו גם את הצומת הנכונה.
לפני שהוא משחרר את ההורה, הוא צריך לשחרר את הילדים גם כן.
ההורה הוא גם החלפה עם שורש.
ההורה הראשון אי פעם, כל כך כמו---סב הסב גדול גדול
או עץ סבתא, ראשון שאנחנו צריכים לשחרר את הרמות ראשונות.
אז לעבור לתחתית, ללא אלה, ולאחר מכן יחזור למעלה, ללא אלה, וכו '
אז זה עץ.
>> עכשיו אנחנו מסתכלים על יער.
יער שבו אתה מניח את כל עצי האפמן.
זה אומר שאנחנו הולכים יש משהו שנקרא עלילה
המכיל מצביע לעץ, כמו גם מצביע לעלילה נקראת הבא.
מה עושה מבנה מסוג זה נראה לך?
זה סוג של אומר שזה שם.
בדיוק כאן.
רשימה מקושרת.
אנו רואים שכאשר יש לנו עלילה זה כמו רשימה מקושרת של עלילות.
יער מוגדר כרשימה מקושרת של מגרשים,
וכך המבנה של יער הוא שאנחנו פשוט הולכים להיות מצביע לחלקה הראשונה שלנו
ועלילה שיש עץ בתוכה או יותר נכון מצביעה על עץ
ולאחר מכן מצביע על המזימה הבאה, וכך הלאה וכך הלאה.
כדי להפוך את יער שאנו מכנים mkforest.
אז יש לנו כמה פונקציות די שימושיות כאן.
יש לנו לבחור בו אתה עובר ביער ולאחר מכן ערך ההחזרה הוא * עץ,
מצביע לעץ.
מה תעשה בחירה הוא שזה ילך אל היער שאתה מצביע על
לאחר מכן להסיר את עץ בתדירות הנמוכה ביותר מזה יער
ולאחר מכן לתת לך מצביע לעץ הזה.
ברגע שאתה קורא לבחור, העץ לא קיים ביער יותר,
אבל ערך ההחזרה הוא הסמן לעץ.
אז יש לך מפעל.
בתנאי שאתה עובר במצביע לעץ שיש תדר שאינו-0,
מה יעשה הוא צמח זה ייקח יער, לקחת את העץ, וצמח שבתוך עץ של היער.
כאן יש לנו rmforest.
דומה כדי להסיר את העץ, שבעצם שחרר את כל העצים שלנו עבורנו,
להסיר יער חינם הכל הכלול באותו יער.
>> אם תסתכלו לתוך forest.c, אנו מצפים לראות את פקודת rmtree לפחות 1 לשם,
כי כדי לפנות זיכרון ביער אם יש עצי יער בזה,
אז סופו של דבר אתה הולך לעשות כדי להסיר את העצים האלה יותר מדי.
אם נסתכל לתוך forest.c, יש לנו mkforest, שכפי שאנו מצפים.
אנו malloc דברים.
נאתחל את העלילה הראשונה ביער כNULL משום שהוא ריק מלכתחילה,
אז אנחנו רואים את בחירה, שמחזירה את העץ עם המשקל הנמוך ביותר, תדר הנמוך ביותר,
ולאחר מכן נפטר שמצומת מסוימת שמצביע על העץ הזה והבא,
אז זה לוקח כי מתוך הרשימה המקושרת של היער.
והנה יש לנו מפעל, אשר מוסיף עץ לרשימה המקושרת.
מה יער עושה זה שומר את זה יפה מסודר עבורנו.
ולבסוף, יש לנו rmforest, וכצפוי, יש לנו מכונה במקום rmtree.
>> כאשר מסתכלים על קוד ההפצה עד כה, huffile.c היה כנראה בהרבה הכי הקשה להבין,
בעוד שאר קבצים עצמם היו די פשוט לעקוב אחריו.
עם הידע של מצביעים ורשימות מקושרות וכאלה שלנו,
היינו מסוגל לעקוב די טוב.
אבל כל מה שאנחנו צריכים באמת לוודא כי אנו מבינים היטב הוא את הקבצים. H
בגלל שאתה צריך להיות קורא פונקציות אלה, העוסק בערכים לחזור האלה,
כדי לוודא שאתה מבין לגמרי איזו פעולה הוא הולך להתבצע
כל פעם שאתה קורא על אחת מהפעולות אלה.
אבל בעצם ההבנה הפנימית שלו היא לא ממש נחוצה, כי יש לנו אלה. קבצי h.
יש לנו עוד 2 קבצים שנותרו בקוד ההפצה שלנו.
>> הבה יתבונן במזבלה.
תזרוק אותו מההערה כאן לוקח קובץ דחוס האפמן
ואז מתרגם ומזבלות כל התוכן שלה החוצה.
כאן אנו רואים שזה קורא hfopen.
זה סוג של שיקוף לקובץ * קלט = fopen,
ואז אתה עובר במידע.
זה כמעט זהה רק שבמקום * קובץ שאתה עובר בHuffile;
במקום fopen אתה עובר בhfopen.
כאן אנו קוראים בכותרת ראשונה, שהוא די דומה לאופן בו אנו קוראים בכותרת
לקובץ מפה סיבי.
מה שאנחנו עושים כאן זה לבדוק אם פרטי הכותרת
מכיל את מספר הקסם הנכון שמצביע על כך שזה קובץ הף בפועל,
אז כל הבדיקות האלה כדי לוודא שהקובץ שפתוח הוא קובץ נשף בפועל או לא.
מה שזה עושה זה מוציא את התדרים של כל הסמלים שאנחנו יכולים לראות
בתוך הטרמינל לתוך טבלה גרפית.
חלק זה הולך להיות שימושי.
יש לו קצת וקורא לאט לאט לתוך סיבי משתנה ולאחר מכן מדפיס אותו.
אז אם אני היה קורא על hth.bin מזבלה, שהוא התוצאה של מתנשם קובץ
באמצעות פתרון צוות, הייתי מקבל את זה.
זה פלט כל הדמויות האלה ואז לשים את התדר שבו הם מופיעים.
אם נסתכל, רובם 0s פרט לזה: H, המופיע פעמים,
ואז T, שמופיע פעם אחת.
והנה יש לנו את המסר האמיתי ב0s ו 1s.
אם נסתכל על hth.txt, שהוא ככל הנראה ההודעה המקורית שנשפה,
אנו מצפים לראות כמה Hs וTs לשם.
באופן ספציפי, אנחנו מצפים לראות רק 1 T ו 2 HS.
הנה אנחנו בhth.txt. זה אכן יש HTH.
כלול בשם, למרות שאנחנו לא יכולים לראות אותו, היא דמות שורה חדשה.
Hth.bin קובץ הף גם קידוד תו השורה החדש גם כן.
הנה כי אנחנו יודעים שהצו HTH שורה חדשה ולאחר מכן,
אנו יכולים לראות כי כנראה H מיוצג רק על ידי אחת 1
ואז T הוא כנראה 01 ולאחר מכן H הבא הוא 1, כמו גם
ואז יש לנו שורה חדשה סומנה בשני 0s.
מגניב.
>> ולבסוף, מכיוון שאנחנו עוסקים במספר. ג ו. קבצי h,
אנחנו הולכים להיות טיעון מורכב למדי למהדר,
אז הנה יש לנו Makefile שעושה מזבלה בשבילך.
אבל בעצם, יש לך ללכת על מה שהופך קובץ puff.c שלך.
Makefile למעשה אינו עוסק בביצוע puff.c בשבילך.
אנחנו עוזבים כי עד לערוך את Makefile.
כאשר אתה נכנסת לפקודה כמו כל לעשות, למשל, זה יעשה את כולם בשבילך.
תרגיש חופשי להסתכל על הדוגמות של Makefile מpset העבר
כמו גם נוסע מזה כדי לראות איך אתה יכול להיות מסוגל לעשות את קובץ פאף
על ידי עריכת Makefile זה.
זה בערך אותו לקוד ההפצה שלנו.
>> ברגע שאנחנו מקבלים דרך את זה, אז הנה רק תזכורת נוספת
של איך שאנחנו הולכים להיות התמודדות עם בלוטות האפמן.
אנחנו לא הולכים להתקשר אליהם צומת יותר; אנחנו הולכים להתקשר אליהם עצים
לאן אנחנו הולכים לייצג את סמלם עם char,
התדר שלהם, את מספר המופעים, עם שלם.
אנחנו משתמשים בזה כי זה יותר מדויק מאשר ציפה.
ואז יש לנו מצביע נוסף לילד משמאל, כמו גם את הילד הנכון.
יער, כפי שראינו, הוא פשוט רשימה מקושרת של עצים.
סופו של דבר, כאשר אנו בונים את קובץ הף,
אנחנו רוצים היער שלנו להכיל רק עץ 1 -
עץ 1, 1 שורש עם ילדים מרובים.
מוקדם יותר, כאשר אנחנו רק עושים עצי האפמן,
יצא לדרכנו על ידי הצבה של כל צומת על המסך שלנו
ואומר שאנחנו הולכים להיות לי צומת אלה,
סופו של דבר הם הולכים להיות העלים, וזה הסמל שלהם, זה התדר שלהם.
ביער שלנו אם אנחנו צריכים רק 3 אותיות, זה יער של 3 עצים.
ואז כמו שאנחנו הולכים על, כאשר הוספנו את ההורה הראשון,
עשינו יער של עצים 2.
הסרנו 2 הילדים האלה מהיער שלנו ולאחר מכן החלפנו אותו בצומת אב
שהיו 2 צומת אלה כילדים.
ולבסוף, בשלב האחרון שלנו עם קבלת הדוגמא שלנו עם כ, ארוחת הבוקר, וCs
יהיה להפוך את ההורה הסופי,
וכן אז שיביא את הסך הכולל שלנו של עצים ביער ל1.
האם כולם רואים איך אתה מתחיל לצאת עם עצים רבים ביער
וסופו של דבר עם 1? אוקיי. מגניב.
>> מה אנחנו צריכים לעשות לפאף?
מה שאנחנו צריכים לעשות הוא להבטיח כי, כמו תמיד, הם נותנים לנו את הסוג הנכון של קלט
כך שאנחנו יכולים למעשה להפעיל את התכנית.
במקרה זה הם הולכים לתת לנו אחרי הוויכוח הראשון שלהם שורת פקודה
עוד 2: את הקובץ שאנחנו רוצים לשחרר את לחץ ואת הפלט של קובץ הדחיסה.
אבל ברגע שאנחנו מוודאים שהם עוברים אותנו בכמות הנכונה של ערכים,
אנחנו רוצים להבטיח שהקלט הוא קובץ הף או לא.
ואז ברגע שאנחנו מבטיחים שזה קובץ הף, אז אנחנו רוצים לבנות את העץ שלנו,
לבנות עץ כזה שיתאים לעץ שהאדם ששלח הודעה שנבנה.
ואז אחרי שאנחנו בונים את העץ, אז אנחנו יכולים להתמודד עם 0s ו 1s שהם העבירו ב,
בעקבות אלה יחד העץ שלנו כי זה זהה,
ואז לכתוב את ההודעה שיצאה, לפרש את הקטעים חזרה לתווים.
ואז, בסוף, כי יש לנו עסק עם מצביעים כאן,
אנחנו רוצים לוודא שאין לנו שום דליפות זיכרון
וכל מה שאנחנו חופשיים.
>> הבטחת שימוש נכון היא כובע ישן לנו עד עכשיו.
אנחנו לוקחים בקלט, שהוא הולך להיות השם של הקובץ כדי לנפח,
ואז אנחנו לציין פלט,
כך שמו של הקובץ לפלט התפוח, אשר יהיה קובץ הטקסט.
זה שימוש. ועכשיו אנחנו רוצים להבטיח שהקלט נשף או לא.
במחשבה לאחור, האם יש משהו בקוד ההפצה שעשויה לעזור לנו
עם ההבנה האם קובץ נשף או לא?
היה מידע בhuffile.c על Huffeader.
אנו יודעים כי כל קובץ הף יש Huffeader משויך אליו עם מספר קסם
כמו גם מערך של התדרים לכל סמל
כמו גם בדיקה.
אנחנו יודעים את זה, אבל אנחנו גם לקחנו להציץ בdump.c,
שבו קרא לקובץ הף.
ואז לעשות את זה, זה היה צריך לבדוק אם זה באמת היה או לא התנשף.
אז אולי תוכל להשתמש dump.c כמבנה לpuff.c.
חזור לpset 4 כאשר היו לנו copy.c הקובץ שהועתק במשולשי RGB
ופרשנו כי להאשמות ושינוי גודל,
באופן דומה, מה שאתה יכול לעשות זה פשוט להפעיל את הפקודה כמו cp dump.c puff.c
ולהשתמש בחלק מהקוד שם.
עם זאת, זה לא הולך להיות פשוט כמו של תהליך
לתרגום dump.c לתוך puff.c,
אבל לפחות זה נותן לך נקודת ההתחלה
כיצד להבטיח שהקלט נשף בפועל או לא
כמו גם כמה דברים אחרים.
יש לנו הבטחתי שימוש נכון והבטיחו כי הקלט התנשף.
בכל פעם שעשינו מה שעשינו בדיקת השגיאות הנכונה שלנו,
כך חזר והפסקת התפקוד אם חלק הכישלון מתרחש, אם יש בעיה.
>> עכשיו מה שאנחנו רוצים לעשות הוא לבנות את העץ עצמו.
אם נסתכל ביער, יש 2 פונקציות עיקריות
שאנחנו הולכים לרוצים להיות מכירים היטב.
יש מפעל הפונקציה בוליאנית שצמחי עץ תדירות הלא-0 בתוך היער שלנו.
ואז יש לך לעבור במצביע ליער ומצביע לעץ.
שאלה מהירה: כמה יערות יש לך כאשר אתה בונה עץ האפמן?
היער שלנו הוא כמו הבד שלנו, נכון?
אז אנחנו רק נצטרך יער 1, אבל אנחנו הולכים ליש עצים מרובים.
אז לפני שאתה קורא למפעל, אתה כנראה הולך לרוצה לעשות יערך.
יש פקודה שלאם אתה מסתכל לתוך forest.h על איך אתה יכול להפוך את יער.
אתה יכול לטוע עץ. אנחנו יודעים איך לעשות את זה.
ואז אתה יכול גם להרים עץ מהיער,
הסרת עץ עם המשקל הנמוך ביותר ונותן לך את המצביע לזה.
מחשבה לאחור לכאשר אנחנו עושים את עצמנו דוגמאות,
כאשר אנחנו מציירים אותו, אנחנו פשוט רק הוספנו את הקישורים.
אבל כאן לא רק הוספת הקישורים,
חושב על זה יותר כמו שאתה מסיר 2 מתוך צומת אלה ולאחר מכן החלפת אותו באחד אחר.
כדי להביע את זה במונחים של בחירה ושתילה,
אתה מתחיל לתפוס 2 עצים ולאחר מכן נטיעת עץ אחר
כי יש 2 העצים האלה שהיו צריכים לאסוף את הילדים.
כדי לבנות את העץ של האפמן, אתה יכול לקרוא את הסמלים והתדרים במטרה
בגלל Huffeader נותן לך את זה,
נותן לך מערך של התדרים.
אז אתה יכול להמשיך ולהתעלם מכל דבר רק עם 0 בזה
כי אנחנו לא רוצים 256 עלים בקצה שלו.
אנחנו רוצים את המספר של עלים שתווים בלבד
כי למעשה משמש בקובץ.
אתה יכול לקרוא בסמלים האלה, וכל אחד מהסמלים האלה שיש להם תדרים שאינם-0,
אלה הולכים להיות עצים.
מה אתה יכול לעשות הוא בכל פעם שאתם קוראים בתדירות שאינו סמל-0,
אתה יכול לשתול עץ שביער.
ברגע שאתה שותל את העצים ביער, אתה יכול להצטרף העצים האלה כאחים,
כך חוזר לנטיעה וקטיף שבו בוחר 2 ולאחר מכן צמח 1,
איפה זה שמפעל 1 הוא האב של 2 הילדים שהיו צריך לאסוף.
אז התוצאה הסופית שלך הולכת להיות עץ בודד ביער.
ככה אתה בונה את העץ שלך.
>> ישנם מספר דברים שיכולים להשתבש כאן
מכיוון שאנחנו עוסקים ביצירת עצים חדשים והתמודדות עם מצביעים ודברים כאלה.
לפני שנים, כאשר היינו לנו עסק עם מצביעים,
כל פעם שאנו malloc'd אנחנו רוצים לוודא שזה לא יחזור אלינו ערך מצביע NULL.
אז בכמה שלבים בתהליך זה יש הולך להיות כמה מקרים
שם התכנית שלך עלולה להיכשל.
מה שאתה רוצה לעשות הוא שאתה רוצה לוודא שאתה לטפל הטעויות האלה,
ובמפרט זה אומר לטפל בם בחינניות,
כל כך אוהב להדפיס הודעה למשתמש אומר להם מדוע התכנית יש להפסיק
ומייד עזב אותו.
לשם הטיפול בשגיאות הזה, זכור כי אתה רוצה לבדוק את זה
בכל פעם שיכולה להיות כישלון.
בכל פעם שאתה עושה מצביע חדש
אתה רוצה לוודא שזה מצליח.
לפני מה שנהגנו לעשות הוא להפוך את המצביע וmalloc חדש,
ואז הייתי בודקים אם מצביע שהוא NULL.
אז יש הולך להיות כמה מקרים שבם אתה פשוט יכול לעשות את זה,
אבל לפעמים אתה בעצם קורא לפונקציה
ובתוך פונקציה, זה אחד שעושה mallocing.
במקרה זה, אם אנחנו מסתכלים אחורה לחלק מהפונקציות בקוד,
חלקם פונקציות בוליאניים.
במקרה המופשט אם יש לנו פונקציה בוליאנית נקראת foo,
בעצם, אנחנו יכולים להניח שבנוסף לכל מה foo עושה,
מאז זה פונקציה בוליאנית, היא מחזירה אמת או שקר -
אמיתי אם תצליח, אם לא שקרי.
אז אנחנו רוצים לבדוק אם ערך ההחזרה של foo הוא אמת או שקר.
אם זה נכון, זה אומר שאנחנו הולכים ברצונך להדפיס מסר כלשהו
ולאחר מכן לצאת מהתכנית.
מה שאנחנו רוצים לעשות הוא לבדוק את ערך ההחזרה של foo.
אם foo מחזיר שקר, אז אנחנו יודעים שנתקלנו בסוג כלשהו של שגיאה
ואנחנו צריכים להפסיק את התכנית שלנו.
דרך לעשות זאת היא מצב שבו יש הפונקציה בפועל עצמו במצב שלך.
אומר foo לוקח בx.
אנחנו יכולים לקבל כתנאים אם (foo (x)).
בעיקרון, זה אומר שאם בסופו של ביצוע foo היא מחזירה אמיתית,
אז אנחנו יכולים לעשות את זה כי יש לו הפונקציה להעריך foo
על מנת להעריך את המצב כולו.
אז ככה אתה יכול לעשות משהו אם הפונקציה מחזירה אמיתית ומוצלחת.
אבל כשאתה בדיקת שגיאות, אתה רק רוצה לפרוש אם הפונקציה שלך מחזירה שקר.
מה אתה יכול לעשות הוא פשוט להוסיף == כוזב או פשוט להוסיף מפץ לפניו
ואז יש לך אם (! foo).
בתוך גופו של המצב שהיית לו כל הטיפול בשגיאות,
כל כך אוהב, "לא ניתן ליצור העץ הזה" ולאחר מכן להחזיר 1 או משהו כזה.
מה שעושה, אם כי, הוא שלמרות שחזר foo שווא -
אומר foo מחזירת אמת.
אז אתה לא צריך להתקשר לfoo שוב. זה טעות נפוצה.
בגלל שזה היה במצב שלך, זה כבר העריך,
אז יש לך כבר את התוצאה, אם אתה משתמש לעשות עץ או משהו כזה
או צמח או בחירה או משהו.
זה כבר יש ערך. זה כבר הוצא להורג.
אז זה מועיל כדי להשתמש בפונקציות וליאניים כתנאי
משום שאם לא אתה בעצם לבצע את גוף הלולאה,
היא מבצעת את הפונקציה בכל מקרה.
>> השני שלנו לצעד האחרון הוא כותב את ההודעה לקובץ.
ברגע שאנו לבנות עץ האפמן, אז כותב את ההודעה לקובץ הוא די פשוט.
זה די פשוט עכשיו פשוט לעקוב 0s ו 1s.
וזאת על ידי אמנה אנו יודעים שבעץ האפמן את 0s מעיד עזב
ו1s מצביע ימין.
אז אם אתם קוראים בטיפי טיפין, בכל פעם שאתה מקבל 0
אתה עוקב אחרי ענף השמאל, ולאחר מכן בכל פעם שאתם קוראים ב1
אתה הולך לבצע את הסניף הנכון.
ואז אתה הולך להמשיך עד שתגיע לעלה
כי העלים הולכים להיות בסופו של הענפים.
איך אנחנו יכולים לדעת אם אנחנו כבר פגענו עלינו או לא?
אנחנו אמרנו את זה לפני.
[תלמיד] אם המצביעים הם NULL. >> כן.
אנחנו יכולים לדעת אם יש לנו להכות עלה אם המצביעים לעצים ימניים ושמאליים שניהם בטלים.
מושלם.
אנחנו יודעים שאנחנו רוצים לקרוא בטיפי טיפין לתוך קובץ הף.
כפי שראינו קודם לכן בdump.c, מה שהם עשו זה שהם קוראים בטיפי טיפין לתוך קובץ הף
ופשוט הדפיס מה החתיכות האלה היו.
אנחנו לא הולכים לעשות את זה. אנחנו הולכים לעשות משהו שהוא קצת יותר מורכב.
אבל מה שאנחנו יכולים לעשות הוא שאנחנו יכולים לקחת את הקטע הזה של קוד שנכתב בקצת.
כאן יש לנו קצת השלמים המייצגים את הקטע הנוכחי שאנו נמצאים בו.
זה דואג iterating כל הביטים בקובץ עד שתגיע לסוף הקובץ.
בהתבסס על כך, ואז אתה הולך לרוצה לקבל קצת סוג של איטרטור
לחצות את העץ שלך.
ולאחר מכן על בסיס אם הסיבי הוא 0 או 1,
אתה הולך רוצה או להזיז את זה איטרטור לשמאל או להזיז אותו ימינה
כל הדרך עד שתגיע לעלה, ולכן כל הדרך עד שהצומת שאתה על
זה אינו מעיד על בלוטות כל עוד.
למה אנחנו יכולים לעשות את זה עם קובץ האפמן אבל לא קוד מורס?
כי בקוד מורס יש קצת אי בהיר.
אנחנו יכולים להיות כמו, אה רגע, שפגענו מכתב בדרך, אז אולי זה הוא המכתב שלנו,
ואילו אם תמשיך רק עוד קצת, ואז הייתי מכה את מכתב נוסף.
אבל זה לא הולך לקרות בקידוד האפמן,
כך אנחנו יכולים להיות סמוכים ובטוחים שהדרך היחידה שאנחנו הולכים להכות אופי
הוא אם ילדי ימין ועל שמאל שהם הצומת של NULL.
>> לבסוף, אנו רוצים לשחרר את כל הזיכרון שלנו.
אנחנו רוצים גם לסגור את תיק הף כי אנחנו כבר עוסקים ב
כמו גם להסיר את כל העצים ביער שלנו.
בהתבסס על היישום שלך, אתה כנראה הולך רוצה לקרוא להסרת יער
במקום באמת עובר את כל העצים בעצמך.
אבל אם עשית את כל עצים זמניים, אתה רוצה לשחרר את זה.
אתה יודע את הקוד שלך טוב ביותר, כך שאתה יודע לאן אתה הקצאת זיכרון.
ואז אם אתה הולך ב, להתחיל אפילו בקרת F'ing לmalloc,
כל פעם שאתה רואה malloc ולוודא שתשחרר את כל זה
אבל אז פשוט עובר את הקוד שלך,
הבנה שבו אתה יכול להיות מוקצה זיכרון.
בדרך כלל אתה יכול פשוט לומר, "בסופו של קובץ אני רק הולך להסרת יער ביער שלי",
אז בעצם לנקות זיכרון ש, חופשי ש,
"ואז אני גם הולך לסגור את התיק, ואז התכנית שלי הולכת להפסיק."
אבל האם זה הזמן היחיד שהתכנית שלך נסגרה?
לא, כי לפעמים יכול להיות שהיה טעות שקרתה.
אולי אנחנו לא יכולים לפתוח את הקובץ או לא יכל לעשות עם עץ אחר
או איזה סוג של שגיאה שקרה בתהליך הקצאת הזיכרון ואז זה חזר NULL.
שגיאה שקרתה ולאחר מכן חזרנו ולהתפטר.
אז אתה רוצה לוודא שכל זמן אפשרי שהתכנית שלך יכולה להפסיק,
אתה רוצה לשחרר את כל הזיכרון שלך שם.
זה לא רק הולך להיות ממש בסוף של הפונקציה העיקרית שאתה יוצא מהקוד שלך.
אתה רוצה להסתכל אחורה לכל מקרה שהקוד שלך קיים פוטנציאל לחזור בטרם עת
ולאחר מכן זיכרון פנוי מה הגיוני.
תגיד אתה קראת להפוך את יער ושחזר שווא.
אז אתה כנראה לא יהיה צורך להסיר יערך
כי אין לך עדיין יער.
אבל בכל נקודה בקוד שבו אתה יכול לחזור בטרם העת
אתה רוצה לוודא שאתה לשחרר את כל זיכרון אפשרי.
>> לכן, כאשר יש לנו עסק עם שחרור זיכרון ויש דליפות פוטנציאליות,
אנחנו רוצים להשתמש בשיקול הדעת שלנו וההיגיון שלנו לא רק
אלא גם להשתמש בValgrind כדי לקבוע אם יש לנו לשחרר את כל הזיכרון שלנו כמו שצריך או לא.
אתה יכול גם להפעיל Valgrind על פאף ואז יש לך גם להעביר את זה
המספר הנכון של טיעוני שורת פקודה כדי Valgrind.
אתה יכול להפעיל את זה, אבל הפלט הוא קצת מסתורי.
אנחנו קבלנו קצת להתרגל לזה עם מאית, אבל אנחנו עדיין צריכות עוד קצת עזרה,
כך אז מפעיל אותו עם כמה דגלים יותר כמו דליפה לבדוק מלא =,
כנראה שייתן לנו קצת יותר על תפוקה מועילה Valgrind.
>> אז עוד טיפ שימושי כאשר אתה ניפוי הוא פקודת ההבדל.
אתה יכול לגשת ליישומו של צוות של הף, להפעיל שעל קובץ טקסט,
ואז פלטת אותו לקובץ בינארי, קובץ בינארי הף, להיות ספציפי.
אז אם אתה מפעיל הנשיפה שלך על אותו הקובץ בינארי,
אז באופן אידיאלי, קובץ טקסט outputted שלך הולך להיות זהה
לזה המקורי שעבר פנימה
כאן אני משתמש hth.txt כדוגמה, וזה אחד לא דבר עליו במפרט שלך.
זה ממש פשוט HTH ואז שורה חדשה.
אבל בהחלט מרגיש חופשי ואתה בהחלט מוזמן להשתמש בדוגמאות ארוכות יותר
לקובץ הטקסט שלך.
>> אתה אפילו יכול לקחת זריקה בדחיסה ולאחר מכן אולי decompressing
חלק מהקבצים שנמצאים בשימוש במאית כמו המלחמה ושלום
או ג'יין אוסטן או משהו כזה - זה יהיה די מגניב - או אוסטין פאוורס,
סוג של התמודדות עם קבצים גדולים יותר, כי אנחנו לא חושבים על זה
אם השתמשנו בכלי הבא כאן, ls-l.
אנחנו רגילים לls, אשר בעצם מפרט את כל התוכן בספרייה הנוכחית שלנו.
עובר בדגל-l בעצם מציג את הגודל של קבצים אלה.
אם אתה עובר את מפרט pset, זה בעצם מנחה אותך דרך יצירת הקובץ בינארי,
של מתנשם זה, ואתה רואה את זה בקבצים קטנים מאוד
עלות השטח של לדחוס אותו ולתרגם את כל המידע הזה
של כל תדרים והדברים כאלה עולה על התועלת הממשית
דחיסה של הקובץ במקום הראשון.
אבל אם אתה מפעיל אותו על איזה קבצי טקסט ארוכים יותר, אז אתה יכול לראות שאתה מתחיל לקבל כמה תועלת
בדחיסה של קבצים אלה.
>> ולבסוף, יש לנו GDB הידידים הוותיק, שבהחלט הולך להיות שימושי מדי.
>> האם יש לנו שאלות על עצי הף או את התהליך של הפיכה אולי העצים
או כל שאלה אחרת בפאף Huff'n?
אוקיי. אני אשאר קצת סיבובים.
>> תודה לכולם. זה היה Walkthrough 6. ומזל טוב.
>> [CS50.TV]