[Powered by Google Translate] [Walkthrough - Проблем Постави 6]
[Zamyla Чан - Универзитетот Харвард]
[Ова е CS50. - CS50.TV]
>> Здраво на сите, и добредојде на можи 6: Huff'n издувам.
Во Huff'n издувам она што го правиме нема да се занимаваат со Хафман компресирана датотека
а потоа puffing го врати, така што декомпресија,
така што ние може да го преведе од 0-ти и 1S дека корисникот испраќа нас
и го претвори назад во оригиналниот текст.
Pset 6 ќе биде прилично кул бидејќи ви се случува да видите некои од алатките
што ќе се користи во pset 4 и pset 5 и вид на комбинирајќи ги во 1 прилично уредни концепт
кога ќе дојде да се размислува за тоа.
>> Исто така, веројатно, pset 4 и 5 беа најголемиот предизвик psets што моравме да понуди.
Значи од сега, имаме ова уште 1 pset во C,
а потоа после тоа ние сме на за веб програмирање.
Значи себе честитам за добивање на над најтешките грпка во CS50.
>> Преселба на за Huff'n издувам, нашите алатникот за овој pset ќе бидат Хафман дрвја,
така разбирање не само како бинарни дрва работа, но, исто така, посебно Хафман дрвја,
како тие се изградени.
А потоа ние ќе имаме многу дистрибуција код во овој pset,
и ние ќе дојдат да се види дека всушност некои од кодот
ние не би можеле да бидат во можност да се разбере целосно уште,
и така тие ќе бидат. в датотеки, но потоа нивните придружни. ж датотеки
ќе ни даде доволно разбирање дека ние треба, така што ние знаеме како тие функции работат
или барем она што тие треба да се направи - нивните влезови и излези -
дури и ако не знаеме што се случува во црна кутија
или не го разбираат она што се случува во црната кутија во рамките.
А потоа конечно, како и обично, ние се справуваме со новите структури на податоци,
одредени видови на јазли кои укажуваат на некои работи,
и така тука има пенкало и хартија не само за процесот на дизајн
и кога ќе се обидуваш да дознаам како вашиот pset треба да работат
но исто така и за време на дебагирање.
Можете да имаат GDB заедно со вашиот пенкало и хартија додека ве однесе долу она што вредностите се,
каде се вашите стрели се укажува, и работи како што.
>> Прво нека се погледне на Хафман дрвја.
Хафман дрва се бинарни дрва, што значи дека секој јазол има само 2 деца.
Во Хафман дрвја карактеристика е дека најчести вредности
се претставени со најмалку бита.
Ние видовме во предавање примери на Morse code, кој вид на консолидиран некои букви.
Ако се обидуваш да се преведе А или Е, на пример,
сте преведување дека често, па наместо да се користи целосен сет на битови
наменети за таа вообичаените тип на податоци, ќе го компресира до помалку,
а потоа тие писма кои се претставени помалку често се претставени со повеќе битови
затоа што може да си го дозволи тоа кога ќе тежат од фреквенциите кои тие букви.
Имаме иста идеја тука во Хафман дрва
каде што се прави еден синџир, еден вид на патот да се дојде до одредени карактери.
А потоа на ликовите, кои имаат најмногу фреквенција
се случува да бидат застапени со најмалку бита.
>> Начинот на кој ќе се изгради дрво Хафман
е со ставање на сите ликови кои се појавуваат во текстот
и пресметување на нивната фреквенција, колку често тие се појавуваат.
Ова или може да биде брои колку пати се појавуваат тие писма
или можеби процент од надвор на сите ликови колку секој од нив се појавува.
И така она што го правите е еднаш имате сето тоа одбележан,
тогаш ќе се погледне за 2 најниска фреквенции, а потоа им се придружи како браќа и сестри
каде тогаш родителот јазол има фреквенција која е збир на 2 деца.
И тогаш од конвенцијата велат дека левата јазол,
те следам дека со следење на 0 гранка,
а потоа најдесната јазол е 1 гранка.
Како што видовме во Morse code, оној gotcha беше дека ако сте имале само звучен сигнал и сигнал
тоа е двосмислена.
Тоа или би можел да биде 1 писмо или тоа би можело да биде низа од 2 букви.
И уште па што Хафман дрвја не е затоа што по природа на ликовите
или нашата крајна вистински ликови се последните јазли на гранка -
ние се однесува на оние што лисја - врз основа на тоа што таму не може да биде било двосмисленост
во однос на која буква ти се обидуваш да се кодираат со серија на битови
бидејќи никаде по битови кои претставуваат 1 писмо
ќе се судрите со друг целиот писмо, и нема да има никаква забуна таму.
Но, ние ќе одиме во примери кои вие момци всушност може да се види дека
наместо нас само ти кажувам дека тоа е вистина.
>> Да ги погледнеме во едноставен пример на едно дрво Хафман.
Имам низа тука дека е 12 карактери.
Имам 4 Како, 6 БС, и 2 CS.
Мојот прв чекор ќе биде да се избројат.
Колку пати ли се појави? Се чини 4 пати во низа.
Б појавува 6 пати, и C се појавува 2 пати.
Секако, јас одам да се каже јас сум користење на Б најчесто,
па сакам да претставуваат Б со најмали број на битови, најмалку бројот на 0-ти и 1S.
И тогаш јас сум исто така, ќе се очекува C до потреба од поголемиот износ на 0-ти и 1S, како и.
Прво она што го направив тука е ги стави во растечки редослед во однос на фреквенцијата.
Гледаме дека Ц и А, тие се нашите 2 најниска фреквенции.
Ние создаваме родител јазол, и тој родител јазол нема писмо поврзани со неа,
но тоа не мора фреквенција, која е сума.
Збирот станува 2 + 4, што е 6.
Потоа ние ја следиме левата гранка.
Ако бевме во тоа 6 јазол, тогаш ние ќе ги следиме 0 за да стигнат до C
а потоа 1 да се дојде до А
Така, сега имаме 2 јазли.
Имаме вредност 6 а потоа ние исто така имаат друг јазол со вредност 6.
И така тие 2 не се само 2 најниска но, исто така, само 2 кои се оставени,
па ние се придружи на оние од друг родител, со сума е 12.
Значи тука имаме Хафман дрво
каде да се дојде до Б, тоа само ќе биде малку 1
а потоа да се дојде до ќе имаме 01 и тогаш C со 00.
Па овде можеме да видиме дека во основа ние сме претставуваат овие знаци со 1 или 2 парчиња
каде Б, како што е предвидено, има најмалку.
И тогаш бевме очекува C да имаат најмногу, но бидејќи тоа е толку мал Хафман дрво,
тогаш А е исто така застапени од 2 парчиња, за разлика некаде во средината.
>> Само за да поминат уште едноставен пример на дрвото Хафман,
велат дека имаат низа "Здраво".
Она што го правите е прв ќе каже колку пати ги H појави во ова?
H појавува еднаш, а потоа е се појавува еднаш и потоа имаме l појавува двапати
и o појавува еднаш.
И така тогаш ние очекуваме која писмо да биде претставен од страна на најмал број на битови?
[Студент] л. >> L. Да. l е во право.
Очекуваме л да бидат застапувани од најмалку бројот на битови
бидејќи л се користи најмногу во низа "Здраво".
Она што јас ќе одам да направите сега е да извлечеш овие јазли.
Имам 1, кој е H, а потоа уште 1, кој е e, а потоа 1, кој е o -
право сега сум ги стави во ред - и потоа 2, кој е л.
Тогаш велам начинот на кој јас се изгради дрво Хафман е да се најде 2 јазли со најмалку фреквенции
и ги направи браќа и сестри, преку создавање на родител јазол.
Тука имаме 3 јазли со најниска фреквенција. Сите тие се 1.
Па еве ние се избере една која ние ќе водат во прв план.
Да речеме јас го избере H и e.
Збирот на 1 + 1 е 2, но овој јазол не мора писмо поврзани со неа.
Тоа само држи вредност.
Сега ќе погледнеме во следните 2 најниска фреквенции.
Тоа е 2 и 1. Тоа може да биде било кој од овие 2, но јас ќе одам да се избере оваа.
Сумата е 3.
А потоа конечно, ми останува само 2 лево, па тогаш што станува 5.
Потоа тука, како што се очекува, ако се пополнат кодирање за тоа,
1s се секогаш на правото гранка и 0-ти се левата.
Тогаш имаме l претставен од само 1 бит а потоа о од 2
и тогаш е со 2, а потоа H паѓа до 3 бита.
Така може да се пренесе оваа порака "Здраво", наместо всушност користење на карактери
од само 0-ти и 1S.
Сепак, не заборавајте дека во неколку случаи имаше врски со нашите фреквенција.
Ние би можеле да имаат или се приклучија на H и о првиот можеби.
Или потоа подоцна кога имавме l претставен од 2
како и се приклучија една претставена со 2, ние може да се поврзани ниту една.
>> И така, кога ви испратиме 0-ти и 1S, кои, всушност, не е гаранција
дека примачот може целосно да ја прочита вашата порака право надвор од лилјак
затоа што тие не би можеле да знаат што одлуката сте го направиле.
Значи, кога ние сме се занимаваат со Хафман компресија,
некако мора да се каже примателот на нашата порака како решивме -
Тие треба да знаат некој вид на дополнителни информации
во прилог на пораката компресирана.
Тие треба да се разбере она дрво, всушност, изгледа,
како ние всушност направени тие одлуки.
>> Тука бевме само прави примери врз основа на реалните брои,
но понекогаш ти исто така може да има дрво Хафман
врз основа на фреквенцијата на која букви, и тоа е точно истиот процес.
Еве јас сум го изразува во однос на проценти или дел,
и така тука иста работа.
Сметам дека 2 најниска, сумира нив, наредните 2 најниска, ги сумира,
додека имам целосна дрво.
Иако би можеле да го направи тоа во секој случај, кога ние сме се занимаваат со процентите,
тоа значи дека ние сме дели работи и кои се занимаваат со децимали или подобро кажано лебди
ако ние сме размислување за структури на податоци на главата.
Што знаеме за плови?
Што е заеднички проблем кога ние сме се занимаваат со лебди?
[Студент] непрецизна аритметика. >> Да. Непрецизност.
Поради подвижна запирка непрецизност, за овој pset така што можеме да бидете сигурни
дека ние не губат сите вредности, тогаш ние всушност ќе треба да се занимаваат со пребројувањето на гласовите.
Значи, ако сте во ситуација да мислам на еден јазол Хафман, ако се погледне назад на структурата тука,
ако се погледне на зелени оние има фреквенција поврзани со неа
како и тоа укажува на еден јазол до неговата лева, како и јазол своето право.
А потоа црвени таму, исто така, имаат карактер поврзани со нив.
Ние нема да направат посебни оние за родителите, а потоа конечниот јазли,
кои ние се однесуваат како лисја, туку тие само ќе имаат NULL вредности.
За секој јазол ќе имаме карактер, симболот дека тој јазол претставува,
тогаш фреквенцијата, како и покажувач на неговата лева детето, како и неговото право дете.
Лисјата, кои се на самото дно, исто така, ќе имаат јазол совети
на нивните лево и нивно право, но бидејќи тие вредности не се укажува на вистински јазли,
што нивната вредност ќе биде? >> [Студент] NULL. >> NULL. Точно.
Еве еден пример за тоа како може да претставуваат фреквенцијата во плови,
но ние ќе треба да се занимаваат со тоа со цели броеви,
па сите што го направив е промена на тип на податок таму.
>> Ајде да одиме за да се малку повеќе од комплексен пример.
Но сега дека ние сме направиле едноставни оние, тоа е само истиот процес.
Ќе најдете 2 најниска фреквенции, сумира фреквенции
и тоа е нова фреквенција на вашиот родител јазол,
кои потоа укажува на неговата лева со 0 гранка и правото со 1 гранка.
Ако имаме стринг "Ова е cs50", тогаш ние брои колку пати е Т рековме,
ж споменато, јас, и, в, 5, 0.
Тогаш она што го направив тука е со црвена јазли Јас само сади,
Реков јас ќе одам да имаат овие карактери на крајот на дното на моето дрво.
Тоа се случува да бидат сите на листовите.
Тогаш она што го направив е што ги подредени по зачестеност во растечки редослед,
и ова е всушност начинот на кој pset код го прави тоа
е тоа што видови на фреквенција, а потоа по азбучен ред.
Така што има броеви, а потоа по азбучен ред од страна на фреквенција.
Тогаш што ќе правам е ќе најдете 2 најниска. Тоа е 0 и 5.
Јас би ги сумира, а тоа е 2. Тогаш јас ќе продолжи, најдете на следните 2 најниска.
Тоа се две 1s, а потоа тие стануваат точки 2, како и.
Сега знам дека мојот следен чекор ќе се приклучи на најмал број,
што е Т, на 1, а потоа избирање на една од јазли кои има 2 како на фреквенција.
Значи тука имаме 3 опции.
Она што јас ќе одам да направите за слајд е само визуелно ги преуредите за вас
така што ќе може да се види како јас сум таа градење.
Што кодот и Вашиот дистрибуција код ќе го направи да се ќе се приклучат на T, една
со 0 и 5 јазол.
Па тогаш тоа суми до 3, а потоа продолжи процесот.
На 2 и 2 сега се најниски, па потоа оние сума до 4.
Секој кој го следи досега? Во ред.
Потоа, по што имаме 3 и 3 кои треба да се собираат,
па повторно јас сум само тоа префрлување, така што можете да видите визуелно, така што тоа не се премногу неуредна.
Потоа имаме 6, а потоа нашите последниот чекор е дека сега имаме само 2 јазли
ние сумира овие да се направи коренот на нашите дрво, која е 10.
И бројот 10 има смисла, бидејќи секој јазол претставен,
нивната вредност, нивната фреквенција број, беше колку пати тие се појави во низа,
и тогаш имаме 5 знаци во нашата низа, така што има смисла.
Ако ние се погледне до колку ние всушност ќе го кодираат,
како што се очекуваше, i и S, кои се појавуваат најчесто
се претставени со најмалку бројот на битови.
>> Бидете внимателни овде.
Во Хафман дрвја случај всушност е важно.
На големи S е различен од мали s.
Ако имавме "Ова е CS50" со големи букви, тогаш мали и само ќе се појави два пати,
ќе биде еден јазол со 2 како неговата вредност, а потоа големи S ќе биде само еднаш.
Па тогаш дрвото ќе се промени структури затоа што всушност има екстра лист овде.
Но збирот сепак, ќе биде 10.
Тоа е она што ние всушност ќе треба да се јавите на проверката,
додавање на сите точки од обвинението.
>> Сега дека ние сме опфатени Хафман дрвја, ние може да се нурне во Huff'n издувам, на pset.
Ние ќе почне со делот на прашања,
и ова ќе ти навикнати со бинарни дрва и како да работат околу тоа:
цртање јазли, создавање на свој typedef struct за еден јазол,
и види како може да се вметне во бинарно дрво, која е сортирани,
traversing него, и работи како што.
Дека знаењето е дефинитивно ќе ви помогнат кога ќе се нурне во издувам Huff'n дел
на pset.
Во стандардна верзија на pset, вашата задача е да се имплементира издувам,
и во хакер верзија вашата задача е да се имплементира Хаф.
Што Хаф не е потребно текст и потоа тоа го преведува во 0-ти и 1S,
така што процесот што го направивме погоре каде што пребројуваше фреквенции
а потоа направи од дрвото, а потоа рече: "Како можам да добијам Т?"
Т е застапена со 100, работи како што,
а потоа Хаф ќе го земе текстот и потоа излез кој бинарни.
Но, исто така, затоа што знаеме дека ние сакаме да им овозможи на нашите примачот на пораката
да се рекреираат исти дрво, исто така, содржи информации за фреквенција се брои.
Потоа со издувам ние се дадени бинарна датотека на 0-ти и 1S
и со оглед исто така, информации за фреквенции.
Ние се преведе на сите оние 0-ти и 1S се врати во оригиналната порака, која беше
па ние сме decompressing тоа.
Ако правиш стандардната верзија, вие не треба да се спроведе Хаф,
па тогаш само може да се користи на вработените имплементација на Хаф.
Постојат инструкции во спецификации за тоа како да го направите тоа.
Можете да го извршите на персоналот имплементација на Хаф по одредени текстуална датотека
а потоа ја користат таа излез како вашиот влез Puff.
>> Како што споменав порано, ние имаме многу на дистрибуција код за оваа.
Одам да се започне одат преку неа.
Одам да го поминат поголемиот дел од времето на. Ж датотеки
бидејќи во. в датотеки, бидејќи имаме. h
и дека ни обезбедува со прототипи на функции,
ние не целосно треба да се разбере токму -
Ако не го разбирате она што се случува во. В датотеки, тогаш не грижете се премногу,
но дефинитивно се обиде да ги погледне, бидејќи тоа би можело да даде некои совети
и тоа е корисно да се користи за читање на другите луѓе код.
>> Гледајќи huffile.h, во коментарите се декларира еден слој на апстракција за Хафман-кодирани датотеки.
Ако одиме надолу, гледаме дека постои максимум 256 симболи кои би можеле да треба кодови за.
Ова ги вклучува сите букви од азбуката - големи и мали -
а потоа симболи и броеви, итн
Тогаш тука имаме магичната бројка идентификување на Хафман-кодирани датотека.
Во рамките на код Хафман тие ќе имаат одредени магичната бројка
поврзани со насловот.
Ова може да изгледа како само случајна магичната бројка,
но ако навистина го преведе на ASCII, а потоа тоа всушност ја искажува Хаф.
Тука имаме struct за Хафман-кодирани датотека.
Има сите овие карактеристики поврзани со датотека Хаф.
Тогаш овде имаме насловот за датотеката Хаф, па ние го нарекуваме Huffeader
наместо на додавање на екстра час, бидејќи тоа звучи исто во секој случај.
Симпатична.
Ние имаме магичната бројка поврзани со неа.
Ако тоа е вистински Хаф датотека, тоа нема да биде бројот погоре, оваа магија еден.
И тогаш ќе имаат низа.
Значи за секој симбол, од кои има 256,
тоа се случува да наведете што фреквенција на оние симболи се во рамките на датотека Хаф.
А потоа конечно, имаме проверка за фреквенции,
која треба да биде на збирот на тие фреквенции.
Значи тоа е она што Huffeader е.
Потоа имаме некои функции кои ја врати следната малку во датотеката Хаф
како и пишува малку во датотеката Хаф, а потоа оваа функција овде, hfclose,
кои, всушност, го затвора датотека Хаф.
Пред тоа, ние се занимаваат со прави само запишам,
но кога ќе имаат датотеки Хаф, наместо fclosing тоа
она што сте, всушност, ќе треба да направите е hfclose и hfopen неа.
Оние кои се специфични функции на Хаф датотеки кои ние ќе треба да се занимаваат со.
Потоа тука читаме во насловот и потоа напишете го насловот.
>> Само со читање на. Ж датотека може да се вид на се добие чувство за она датотека Хаф може да биде,
она што карактеристики има, без всушност да одат во huffile.c,
кои, ако се нурне во, ќе биде малку посложени.
Таа ги има сите на датотека I / O тука се занимаваат со покажувачи.
Овде гледаме дека кога ние го нарекуваме hfread, на пример, тоа е уште се занимаваат со fread.
Ние не сме да се ослободиме од тие функции во целост, но ние сме испраќање на оние што треба да се преземат грижата за
во внатрешноста на датотека Хаф, наместо за правење на сите за тоа самите себеси.
Можете да се чувствуваат слободни да скенира преку ова ако сте љубопитни
и да си одат и кора слој назад малку.
>> Следниот датотека што ние ќе треба да се погледне е tree.h.
Пред во можи слајдови рековме дека очекуваме Хафман јазол
и ние направивме typedef struct јазол.
Очекуваме да има симбол, фреквенција, а потоа 2 јазол ѕвезди.
Во овој случај она што го правиме е тоа е во суштина иста
освен наместо на јазол ние ќе ги наречеме дрвја.
Имаме функција која кога ќе се јавите направи дрво тоа ви се враќа дрво покажувач.
Вратете се на правопис, кога ќе се прави нов јазол
ти рече јазол * нов збор = Примерок (sizeof) и работи како што.
Во суштина, mktree ќе се занимаваат со тоа за вас.
Слично на тоа, кога ќе сакате да го отстраните дрво,
така што во суштина ослободување на дрвото кога ќе завршиш со него,
наместо експлицитно повикување бесплатно на тоа, ти си, всушност, само ќе ја користите функцијата rmtree
каде ќе помине во покажувачот во тој дрво, а потоа tree.c ќе се грижи за тоа за вас.
>> Ние се погледне во tree.c.
Ние очекуваме истите функции, освен да го видиш имплементација, како и.
Како што се очекуваше, кога ќе се јавите mktree тоа mallocs големината на дрво во покажувач,
иницијализира сите вредности на NULL вредност, така 0-ти или NULLS,
а потоа се враќа покажувач на тоа дрво дека сте само malloc'd за вас.
Еве кога ќе се јавите отстрани дрвото за прв пат прави сигурни дека не сте двојно ослободување.
Тоа го прави сигурни дека всушност имаат дрво кое сакате да го отстраните.
Тука, бидејќи дрво, исто така, вклучува своите деца,
Што тоа не е тоа рекурзивно повици отстранат дрво од левата јазол на дрво
како и правото јазол.
Пред да го ослободи родителот, треба да ги ослободи децата.
Родител е исто така заменлив со корен.
Првиот родител, па како пра-пра-пра-пра-дедо
или баба дрво, прво треба да се ослободи по нивоа во прв план.
Значи напречни до дното, без оние, а потоа се врати нагоре, бесплатни оние, итн
Значи тоа е дрво.
>> Сега гледаме шумата.
Шума е местото каде што ќе поставите на сите ваши Хафман дрвја.
Тоа е велејќи дека ние ќе имаме нешто што се нарекува заговор
кој се состои покажувач до дрвото, како и покажувач на заговор наречен следната.
Што структура го прави овој вид на изгледа?
Тој вид на тоа дека таму.
Право овде.
А поврзани листа.
Гледаме дека кога имаме заговор тоа е како поврзани листа на парцели.
А шумата е дефинирана како се поврзани листа на парцели,
и така структурата на шумите е ние сме само ќе мора покажувач на нашата прва заговор
и дека Парцела има едно дрво во неа или подобро укажува на дрвото
а потоа укажува на следното заговор, па натаму и така натаму.
Да се ​​направи шума што ние го нарекуваме mkforest.
Тогаш имаме некои прилично корисни функции тука.
Имаме собереш каде што ќе помине во шумата и тогаш вратената вредност е едно дрво *,
покажувач на дрво.
Што пик ќе го направите е дека ќе одат во шумата дека сте укажува на
потоа отстранете дрво со најниска фреквенција од таа шума
и потоа да ви даде покажувач на тоа дрво.
Откако ќе се јавите собереш, дрвото нема да постои во шумата веќе,
но вратената вредност е покажувач на тоа дрво.
Тогаш имате растение.
Под услов да помине во покажувач на дрво кој има не-0 фреквенција,
што фабриката ќе направите е тоа ќе потрае шумата, да ги преземе дрво и растение кое дрво во внатрешноста на шумата.
Тука имаме rmforest.
Слични да се отстранат дрво, што во основа ослободени сите наши дрва за нас,
отстрани шума ќе се ослободи се содржани во таа шума.
>> Ако ги погледнеме во forest.c, ќе очекуваат да видат најмалку 1 rmtree команда во таму,
бидејќи за слободна меморија во шумата ако шума има дрвја во него,
потоа на крајот ви се случува да мора да се отстранат оние дрвја премногу.
Ако ги погледнеме во forest.c, ние си имаме mkforest, која е како што очекував.
Ние Примерок работи.
Ние се иницијализира на прво заговор во шумата како NULL, бидејќи тоа е празна да започне со тоа,
тогаш можеме да видиме мотиката, која се враќа на дрвото со најниска тежина, најниската фреквенција,
а потоа добива ослободи од таа јазол што укажува на тоа дрво и следната,
па го зема дека од поврзани листа на шумата.
И тогаш тука имаме фабриката, која внесува дрво во поврзани листа.
Што шума не е тоа убаво го чува складирано за нас.
А потоа конечно, имаме rmforest и, како што се очекуваше, имаме rmtree наречен таму.
>> Гледајќи дистрибуција код досега, huffile.c веројатно беше далеку од најтешко да се разбере,
додека други датотеки самите се прилично едноставни да го следат.
Со нашето знаење за совети и поврзани листи и такви,
ние бевме во можност да го следат многу добро.
Но, сите ние треба навистина да бидете сигурни дека ние се разбере целосно е. Ж датотеки
затоа што треба да се повикуваат на тие функции, кои се занимаваат со оние враќање вредности,
така бидете сигурни дека ќе се разбере целосно она што акција се случува да се изврши
кога ќе се јавите една од тие функции.
Но всушност разбирање во него не е сосема неопходно бидејќи имаме оние. Ж датотеки.
Имаме 2 повеќе датотеки лево во нашата дистрибутивна код.
>> Да ги погледнеме на депонија.
Шутнат од страна на неговиот коментар овде зема Хафман-компресирана датотека
а потоа ги преведува и депонии сите негови содржини надвор.
Овде гледаме дека тоа е повикувајќи hfopen.
Ова е вид на слика на датотека * внесување = fopen,
а потоа ќе помине во информацијата.
Тоа е речиси идентични, освен наместо на датотека * си поминува во Huffile;
наместо fopen сте поминува во hfopen.
Еве што читаме во насловот прво, кој е вид на слично на тоа како што читаме во насловот
за битмапа датотеки.
Она што го правиме тука е проверка за да види дали технички податоци
содржи правото магичната бројка што укажува на тоа дека тоа е вистински Хаф датотека,
тогаш сите од овие проверки за да бидете сигурни дека датотеката што ние отворен е вистински huffed датотека или не.
Што тоа не е тоа излези на фреквенциите на сите симболи кои можеме да видиме
во рамките на терминал во графички табела.
Овој дел ќе биде корисно.
Таа има малку и гласи малку по малку во променлива малку, а потоа печати.
Значи, ако јас да се јавам депонија на hth.bin, која е резултат на huffing датотека
користење на персоналот решение, јас ќе ја добие ова.
Тоа е Ставање сите тие ликови и потоа ставање на фреквенцијата на која тие се појавуваат.
Ако ги погледнеме, повеќето од нив се 0-ти освен за ова: H, кој се појавува двапати,
а потоа Т, која се појавува еднаш.
И тогаш ја имаме вистинската порака во 0-ти и 1S.
Ако ги погледнеме hth.txt, што е веројатно оригиналната порака, која беше huffed,
ние очекуваме да видите некои Hs и Т таму.
Поточно, ние очекуваме да се види само 1 T и 2 ХС.
Тука сме во hth.txt. Тоа навистина има HTH.
Вклучени во таму, иако не можеме да го видиме, е линија карактер.
Датотеката Хаф hth.bin е исто така кодирање на линија карактер, како и.
Тука, затоа што знаеме дека наредбата е HTH, а потоа линија,
можеме да видиме дека веројатно H е претставена со само еден 1
а потоа T е веројатно 01 и потоа на следниот H е 1, како и
и тогаш имаме нова линија означена со два 0-ти.
Кул.
>> А потоа конечно, затоа што ние сме се занимаваат со повеќе. В и. Ж датотеки,
ние ќе имаат доста сложени аргумент на компајлерот,
и така тука имаме Makefile што го прави депонија за вас.
Но, всушност, треба да одат за правење на своја сопствена puff.c датотека.
На Makefile всушност не се занимава со правење puff.c за вас.
Тргнуваме дека до вас да ги уредувате Makefile.
Кога ќе внесете ја командата како прават сите, на пример, тоа ќе го направи сите од нив за вас.
Слободно да се погледне на примери на Makefile од минатото pset
како и ќе отиде на ова да видиме колку може да биде во можност да се направи вашиот издувам датотека
со уредување на оваа Makefile.
Тоа е за тоа за нашата дистрибутивна код.
>> Откако сме добиле преку тоа, тогаш тука е само уште еден потсетник
за тоа како ние ќе треба да се занимаваат со Хафман јазли.
Ние нема да се нарекувајќи ги јазли повеќе, ние ќе треба да се ги повикувам дрва
каде што ќе треба да се застапуваат нивните симбол со знак,
нивната фреквенција, бројот на појавувања, со цел број.
Ние сме користење на тоа, бидејќи тоа е попрецизно отколку со подвижна запирка.
И тогаш имаме уште покажувачот лево детето, како и право дете.
А шума, како што видовме, е само поврзани листа на дрвјата.
На крајот на краиштата, кога градиме до нашите Хаф датотека,
ние сакаме нашите шуми да содржи само 1 дрво -
1 дрво, 1 корен со повеќе деца.
Претходно кога бевме само што нашите Хафман дрвја,
ние започна со ставање на сите јазли врз нашите екран
и велејќи ние ќе ги имаат овие јазли,
на крајот тие ќе бидат лисја, и ова е нивен симбол, ова е нивната фреквенција.
Во нашата шума, ако ние само треба 3 букви, тоа е шума од 3 дрва.
А потоа како да одиме на, кога ќе додаде првиот родител,
ние направивме една шума од 2 дрвја.
Ние отстранета 2 на оние деца од нашата шума и потоа се заменува со еден родител јазол
кои имаа оние 2 јазли како деца.
А потоа, конечно, нашиот последен чекор со правење нашиот пример со As, Bs и акредитиви
ќе биде да ја донесе конечната родител,
и така тогаш тоа ќе донесе нашите вкупниот бројот на дрвјата во шумата 1.
Не сите се види како ќе почнете да излегува со повеќе дрвја во вашиот шума
и завршуваат со 1? Во ред. Кул.
>> Што треба да направите за издувам?
Она што треба да направите е да се осигура дека, како и секогаш, тие ни даваат право тип на влез
така што ние всушност може да ја стартувате програмата.
Во овој случај тие ќе бидат ни даваат по нивната прва командната линија аргумент
2 повеќе: датотеката што сакате да декомпресија и излез на декомпресиран датотека.
Но еднаш сме бидете сигурни дека тие не помине во точниот износ на вредности,
сакаме да се осигураме дека влезот е датотека Хаф или не.
А потоа откако ќе гарантира дека тоа е датотека Хаф, тогаш ние сакаме да ја градиме нашата дрво,
изгради дрвото како што тоа се совпаѓа со дрво дека лицето кое ја испратил пораката изграден.
Потоа, откако ќе се изгради на дрвото, а потоа можеме да се справиме со 0-ти и 1S дека тие поминаа во,
следат оние долж нашите дрво, бидејќи тоа е идентична,
а потоа пишуваат дека пораката, толкуваат на битови назад во карактери.
А потоа на крајот, бидејќи ние сме се занимаваат со покажувачи тука,
ние сакаме да се осигураме дека можеме немаат меморија протекување
и дека слободно сè.
>> Обезбедување на соодветна употреба е стара шапка за нас до сега.
Ние се во влез, кој ќе биде името на датотеката да се издувам,
а потоа наведете излезна,
па името на датотеката за умирам излез, која ќе биде текстуална датотека.
Тоа е употреба. И сега сакаме да се осигураме дека влезот е huffed или не.
Размислување назад, немаше ништо во дистрибуцијата код кој може да ни помогне
со разбирање дали датотеката е huffed или не?
Имаше информации во huffile.c за Huffeader.
Ние знаеме дека секој фајл Хаф има Huffeader поврзани со неа со магичната бројка
како и низа на фреквенции за секој симбол
како и проверката.
Ние знаеме тоа, но ние исто така, зеде погледнеме dump.c,
во која читав во датотека Хаф.
И така да го стори тоа, таа мораше да се провери дали тоа навистина беше huffed или не.
Па можеби и ние може да се користи dump.c како структура за нашиот puff.c.
Назад кон pset 4 кога имавме датотеката copy.c дека копирани во RGB тројки
и ние толкува дека за Whodunit и големината,
Слично на тоа, она што може да направите е само да ја извршите командата како ср dump.c puff.c
и употреба на некои од кодот таму.
Сепак, тоа нема да биде лесно на процесот
за преведување на вашата dump.c во puff.c,
но барем тоа ви дава некаде да се започне
како да се обезбеди дека влезот е всушност huffed или не
како и неколку други работи.
Имаме обезбедено правилно користење и гарантира дека влезот е huffed.
Секој пат дека ние сме направиле тоа ние сме го направиле нашиот правилно грешка проверка,
па враќање и напуштање на функцијата ако некои неуспех се јавува, ако има некој проблем.
>> Сега она што сакате да го направите е да се изгради вистински дрво.
Ако ги погледнеме во шума, постојат 2 основни функции
дека ние ќе сакаат да станат многу запознаени со.
Тука е Булова функција растение кое растенија не-0 фреквенција дрво во внатрешноста на нашите шуми.
И така таму ќе помине во покажувач кон шумата и покажувач на дрво.
Брзи прашање: Колку шуми ќе имате кога ќе градиме дрво Хафман?
Нашите шуми е како нашата платно, нели?
Па ние сме само ќе треба 1 шума, но ние ќе имаат повеќе дрвја.
Значи пред да се јавите фабрика, ти си веројатно ќе сакате да направите вашиот шума.
Постои команда за тоа ако се погледне во forest.h за тоа како можете да направите шума.
Можете да засади дрво. Знаеме како да го направите тоа.
И тогаш исто така можете да изберете дрво од шумата,
отстранување на дрво со најниска тежина и ви даваат покажувач за тоа.
Размислување назад кога бевме прави примери себе,
кога бевме тоа извлекувањето, ние едноставно само додава линкови.
Но, тука, наместо само додавање на линкови,
мислам на тоа повеќе како сте отстранување 2 на оние јазли, а потоа негово заменување со друг.
Да го изразат дека во однос на подигање и садење,
сте подигање 2 дрвја, а потоа садат друго дрво
дека има оние 2 дрвјата кои што сте го одбрале како деца.
Да се ​​изгради дрво Хафман, можете да прочитате во симболи и фреквенции со цел
бидејќи Huffeader дава тоа за вас,
ви дава низа на фреквенции.
Па можете да одите напред и едноставно игнорирајте ништо со 0 во него
бидејќи ние не сакаме 256 листови на крајот од неа.
Ние само сакаме бројот на листови кои се ликови
кои се всушност користени во датотеката.
Можете да прочитате во оние симболи, и секоја од овие симболи кои имаат не-0 фреквенции,
тие се случува да бидат дрвја.
Што можете да направите е секој пат кога ќе го прочитате во не-0 фреквенција симбол,
ќе може да посади тоа дрво во шумата.
Откако ќе засади дрвца во шумата, можете да се приклучат на оние дрвја како браќа и сестри,
па ќе се вратам на садење и изборот каде ќе ги собереш 2, а потоа растенијата 1,
каде што 1 дека фабриката е родител на 2 деца кои што сте го одбрале.
Па тогаш вашиот Крајниот резултат ќе биде една дрво во шумата.
Тоа е како да изградите вашиот дрво.
>> Постојат неколку работи што може да тргне наопаку тука
бидејќи ние сме се занимаваат со создавање на нови дрва и се занимаваат со совети и работи како што.
Пред кога ние се занимаваат со покажувачи,
секогаш кога malloc'd сакавме да бидете сигурни дека тоа не ни се врати NULL покажувачот вредност.
Па на неколку чекори во овој процес таму ќе биде неколку случаи
каде што вашата програма може да не успее.
Што сакате да направите е да сакате да бидете сигурни дека ќе се справи со овие грешки,
и во спецификации што се вели да се справи со нив благодатно,
Значи како испечатите порака до корисникот кажувајќи им зошто на програмата е да престанам
а потоа брзо се повлече.
Да го направите ова грешка ракување, не заборавајте дека сакате да го проверите
секој пат дека би можел да биде неуспех.
Секој пат кога ќе се прави нов покажувач
вие сакате да бидете сигурни дека тоа е успешна.
Пред она што се користи да направите е да се направи нов покажувач и Примерок тоа,
и тогаш ние ќе провери дали покажувачот е NULL.
Па таму се случува да биде некои случаи, каде што само може да го направи тоа,
но понекогаш ти си, всушност, нарекувајќи функција
Во таа функција, тоа е оној кој го прави на mallocing.
Во тој случај, ако се погледне назад на некои од функциите во рамките на код,
некои од нив се Булови функции.
Во апстрактни случај ако имаме Булова функција наречена foo,
основа, можеме да претпоставиме дека во прилог на тоа што foo не,
бидејќи тоа е Булова функција, го враќа точно или неточно -
точно ако е успешна, лажни ако не.
Значи, ние сакаме да се провери дали повратната вредност на foo е точно или неточно.
Ако е неточно, тоа значи дека ние ќе сакате да се печати некој вид на порака
а потоа да престанам програмата.
Она што сакаме да направите е да се провери повратната вредност на foo.
Ако foo враќа false, тогаш знаеме дека ние се сретнал некој вид на грешка
и ние треба да се откажат од нашата програма.
Еден начин да го направите ова е да има состојба каде вистинските самата функција е вашата состојба.
Велат foo зема во х.
Ние може да има како услов ако (foo (x)).
Во суштина, тоа значи дека ако на крајот на извршување foo го враќа точно,
тогаш можеме да го направите ова, бидејќи функцијата има да се оцени foo
со цел да се оцени целата состојба.
Па тогаш тоа е како можете да направите нешто ако функцијата враќа точно и е успешна.
Но, кога сте грешка проверка, вие само сакате да се откажете, ако вашата функција враќа false.
Што можете да направите е само да додадете == лажни или само додадете тресне пред него
а потоа ќе мора if (! foo).
Во рамките на тој орган на таа состојба ќе имаат сите на грешка ракување,
Значи како "Не можам да креирам ова дрво", а потоа се врати 1 или нешто слично.
Она што го прави тоа, сепак, е дека иако foo врати лажни -
Велат foo враќа точно.
Тогаш не треба да се јавите foo повторно. Тоа е честа заблуда.
Бидејќи тоа е во вашата состојба, тоа е веќе оценети,
па имате резултат ако сте со користење направи дрво или нешто слично
или растителни или пик или нешто.
Таа веќе има таа вредност. Тоа е веќе извршена.
Така, тоа е корисно да се користи Булови функции како услов
бидејќи тоа дали или не сте всушност извршување на телото на јамка,
го извршува функцијата во секој случај.
>> Нашиот втор до последното чекор е пишување на порака до датотеката.
Откако ќе се изгради на дрвото Хафман, а потоа пишување на порака до датотека е прилично јасна.
Тоа е прилично јасна сега само да го следат 0-ти и 1S.
И така од конвенцијата знаеме дека во дрво Хафман на 0-ти укажуваат лево
и 1s укажуваат право.
Па тогаш ако го прочитате во малку од малку, секогаш кога ќе добие 0
ќе следат левата гранка, а потоа секој пат кога ќе прочитате во 1
ви се случува да се следи вистинскиот гранка.
А потоа ви се случува да продолжи додека не го погоди еден лист
бидејќи лисјата се случува да биде на крајот од гранките.
Како што може да каже дали ние сме хит лист или не?
Ние тоа го рече пред тоа.
[Студент] Ако совети се ништовни. >> Да.
Ние може да каже дали ние сме хит лист ако совети за двете лево и десно дрвја се ништовни.
Совршена.
Знаеме дека сакате да го прочитате во малку по малку во нашите Хаф датотека.
Како што видовме досега во dump.c, она што се случи е дека тие читаат во малку по малку во датотеката Хаф
и само печатени од она што тие делови беа.
Ние нема да се прави тоа. Ние ќе се прави нешто што е малку посложена.
Но, она што можеме да направиме е што може да се земе дека малку на кодот кој гласи во малку.
Тука имаме цел број малку претставуваат сегашниот малку дека ние сме на.
Ова се грижи за процесирањето на сите битови во датотека додека не го погоди крајот на датотеката.
Врз основа на тоа, тогаш ви се случува да сакаат да имаат некој вид на iterator
да напречни дрвото.
А потоа врз основа на тоа дали малку е 0 или 1,
сте ќе сакате или да се движат дека iterator на лево или преместите во право
по целиот пат додека не го погоди еден лист, па сите на патот до тој јазол дека сте на
не укажуваат на повеќе јазли.
Зошто ние да го правиме ова со датотека Хафман, но не Morse code?
Бидејќи во Morse code има малку двосмисленост.
Ние може да биде како, ох чекаат, ние сме хит писмо на патот, па можеби и ова е нашето писмо,
а ако продолжи малку подолго, тогаш ние ќе ја погодеше друго писмо.
Но, тоа нема да се случи во Хафман кодирање,
така што може да бидат сигурни дека единствениот начин на кој ние ќе ја погоди карактер
е ако лево и десно деца кои јазол се ништовни.
>> Конечно, ние сакаме да ги ослободи сите од нашата меморија.
Ние сакаме да и блиски на датотеката Хаф дека ние сме биле занимаваат со
како и отстрани сите дрвја во нашата шума.
Врз основа на вашата институција, ти си веројатно ќе сакате да го повикате отстрани шума
наместо всушност минува низ сите на дрвјата себе.
Но, ако сте го направиле било привремени дрвја, ќе сакате да се ослободи тоа.
Знаеш вашиот код најдобрите, па да знаете каде сте доделување меморија.
И така, ако одите во, почнете со дури контрола F'ing за Примерок,
види кога Примерок и прави сигурни дека ќе ги ослободи сите на кои
но тогаш само оди преку вашиот код,
разбирање каде што може да се распределени меморија.
Обично вие само може да се каже, "На крајот на датотеката јас сум само ќе ги отстрани шума на мојата шума"
Значи, во основа јасно дека меморијата, слободна дека,
"И тогаш јас сум исто така, ќе го затвори датотека, а потоа мојата програма ќе се откажам."
Но, дали е тоа единствениот пат дека вашата програма поднесе оставка?
Не, затоа што понекогаш може да е грешка што се случи.
Можеби не можеме да отворите датотека или ние не би можеле да направат друго дрво
или некој вид на грешка се случи во распределбата на меморија процес и затоа таа се врати NULL.
Грешка се случи, а потоа се вративме и се повлече.
Па тогаш ќе сакате да бидете сигурни дека сите можни време дека вашата програма може да престанам,
сакате да ги ослободи сите на вашата мемориска таму.
Тоа не е само ќе биде на самиот крај од главната функција што ќе ја завршите вашиот код.
Сакате да се погледне назад во секој случај дека вашиот код потенцијално може да се врати предвреме
и тогаш слободно без оглед меморија прави смисла.
Велат дека се јавил направи шума и дека се врати лажни.
Тогаш веројатно нема да има потреба да ги отстраните вашите шума
затоа што немаат шумата сеуште.
Но, во секоја точка во кодот каде што може да се врати предвреме
вие сакате да бидете сигурни дека ќе ги ослободи сите можни меморија.
>> Значи, кога ние сме се занимаваат со ослободување на меморија и има потенцијал протекување,
ние сакаме да го користи само наше мислење и нашата логика
но исто така се користи Valgrind да се утврди дали ние сме ослободени сите наши меморија правилно или не.
Можете или да го извршите Valgrind на издувам, а потоа мора да се, исто така, го предадете
вистинскиот број на командната линија аргументи Valgrind.
Можете да го извршите тоа, но на излез е малку криптичната.
Ние добивано и малку се користи за да со правопис, но ние сепак треба малку повеќе помош,
па потоа трча со неколку знамиња како течење проверете = полн,
дека веројатно ќе ни даде некои повеќе корисни излез на Valgrind.
>> Па уште еден корисен совет кога сте дебагирање е команда разл.
Можете да пристапите до имплементација на персоналот на Хаф, работи кои на еден текст фајл,
а потоа излез на бинарна датотека, бинарен Хаф датотека, да бидат конкретни.
Потоа, ако се кандидира свој здив на тој бинарна датотека,
тогаш идеално, вашиот outputted текстуална датотека ќе биде идентична
на оригиналниот оној што го донесе внатре
Еве јас сум со користење hth.txt како пример, а тоа е еден зборуваше во вашиот спецификации.
Тоа е буквално само HTH, а потоа нова линија.
Но дефинитивно се чувствувам слободно и вие сте дефинитивно охрабруваат да ги користат повеќе примери
за вашиот текст фајл.
>> Можете дури и да се сними во можеби компресирање а потоа декомпресија
некои од фајловите што ќе се користи во правопис како Војна и мир
или Џејн Остин или нешто слично - тоа ќе биде вид на кул - или Остин сили,
вид на справување со поголеми фајлови, бидејќи ние нема да дојде до тоа
ако ние се користи следната алатка тука, ls-l.
Ние сме навикнати да ls, што во основа ги содржи сите содржини во нашите тековниот директориум.
Предавање на знамето-l, всушност, ја покажува големината на овие датотеки.
Ако одите преку спецификации pset, тоа всушност ќе шета низ создавање на бинарна датотека,
на huffing него, и ќе видите дека за многу мали датотеки
просторот трошоците за компресирање на неа, и преведување сите тие информации
на сите фреквенции и работи како што надминува реалните корист
на компресирање на датотеката на прво место.
Но, ако тоа се кандидира на некои повеќе текстуални датотеки, тогаш може да се види дека ќе почнете да се добие некоја корист
во компресирање на овие датотеки.
>> А потоа конечно, имаме нашиот стар другар GDB, која е дефинитивно ќе дојде во рака премногу.
>> Дали имаме било какви прашања на Хаф дрва или процесот можеби за изработка на дрвја
или било какви други прашања за Huff'n издувам?
Во ред. Јас ќе останат околу за малку.
>> Ви благодариме, секого. Ова беше можи 6. И среќа.
>> [CS50.TV]