[Powered by Google Translate] [Валктхроугх - Проблем Сет 5]
[Замила Цхан - Универзитет Харвард]
[Ово је ЦС50. - ЦС50.ТВ]
>> У реду. Поздрав свима, и добродошли у Валктхроугх 5.
>> Псет5 је Грешке у којој ћемо бити прави за проверу правописа.
Спелл-даме су изузетно важни.
Да се ​​ово икада десило?
Ви сте веома радите, веома оставе на папиру за сукоб
и онда још на крају добија врло сјај Радета као Д или Д =
а све због тога што сте паштета спојлер на китове широком речи.
Да, лектура своје паприке је ствар од, крајње импотенција.
То је проблем који утиче на Манли, Манли студената.
Једном сам рекао мојим Ситх разреда мучитеља да никада не би у добром колеги.
И то је све што сам икада желео, то је све било које дете жели у мојим годинама,
само да уђу у добром колеги.
И то не било какав колега. Не желим да идем на Слоноваче правној колеге.
Дакле, ако нисам побољшање, нестао би моји снови ће да Харварду,
Јале, или затвор - знате, у затвору, Њу Џерси.
Тако сам себи имам провере правописа.
То је мало извод из једног од мојих омиљених уметника изговорена реч, Тејлор Малом.
У сваком случају, како каже, значај има проверу правописа је веома важно.
>> Дакле, добродошли на Валктхроугх 5, у којој ће говорити о псет5: Грешке,
у којој ћемо бити доношење нашу сопствену проверу правописа.
Тоолбок за ову недељу, расподела код, биће важно да погледате
само да разуме различите функције које ваш речник ће имати.
Ми смо заправо ће бити потребе више. Ц датотека које заједно чине наш псет.
И тако гледа кроз различите аспекте, иако заправо не уређивање
један од фајлова, спеллер.ц, знајући како се то ради у односу на дицтионари.ц,
којима ћемо писати, ће бити прилично важно.
Тхе псет спец такође садржи доста корисних информација
у смислу ствари које можете да претпостављају, правила и сличне ствари,
па будите сигурни да прочитате спецификације псет пажљиво савете.
А када су у недоумици по правилу, или нешто слично, онда увек погледајте псет спец
или Разговарајте.
Ова псет ће у великој мери ослањају на показивача,
па смо желели да се уверите да разумемо разлику између додајући звезда
испред имена показивач и амперсандс, како да их ослободе, итд
Тако што мајстор показивача ће бити веома корисно у овом проблематиком сету.
Ми ћемо да погледамо у повезаним листама мало више,
где имамо елементе који зовемо чворове који имају обе вредности, као и показивач
на следећи чвор, и тако суштински повезујући различите елементе један за другим.
Постоји неколико различитих опција спровођења своју стварну речник.
Ми ћемо да погледамо у две главне методе, што је хасх табеле, а затим покушава.
У оба њих, они укључују неку врсту појма повезану листу
где сте елементе повезане једна са другом.
И тако ћемо да погледамо о томе како ћете можда бити у могућности да раде око повезаним листама,
створи их, идите у смислу како да се, на пример, убаците у њега чвор
или бесплатно све чворове као добро.
У смислу ослобадјања чворова, што је заиста важно
да кад год смо маллоц меморије, затим смо га ослободили.
Дакле, желимо да се уверите да нема показивач иде унфреед, да немамо никакве цурење меморије.
Ми ћемо увести алатку која се зове Валгринд који покреће свој програм
и проверава да ли су све меморије коју издваја се затим ослободио.
Ваша псет само заврши када се ради и да има пуну функционалност,
али такође, Валгринд вам говори да нисте нашли никакве меморијске цурења.
Коначно, за ову псет, ја заиста желим да нагласим -
Мислим, као и обично, ја сам дефинитивно поборник коришћења оловку и папир за твој проблем сетовима,
али за овај један, мислим да оловка и папир ће бити посебно важно
када желите да будете цртање стрелице ствари и разумевање како ствари раде.
Дакле, дефинитивно покушајте да користите оловку и папир да скрене ствари пре него што се кодирање
јер она може да добије мало неуредна.
>> Прво идемо у повезаним листама мало.
Повезане листе се састоји од чворова, где сваки чвор има неку вредност у вези са њом,
као и показивач на следећи чвор после њега.
Пар ствари важних са повезаним листама су да треба да запамтите
где је наш први чвор је, а затим једном знамо где је први чвор је,
на тај начин можемо приступити чвор да су први чвор указује на
а затим и један после тога и онај после тога.
А онда последњи елемент у повезаној листи је тог чвора показивач
увек ће да укаже на НУЛЛ.
Када чвор бодова НУЛЛ, онда знате да сте стигли на крај листе,
да је чвор је последњи, да не постоји ништа после тога.
Овде у овој шеми, видећете да су стрелице су показивачи,
а плави одељак где се вредност складишти,
и онда црвени оквир са показивачем То је чвора показивач
указујући на следећи чвор после њега.
И тако ви овде видите, Д чвор би указивао на НУЛЛ, јер је последњи елемент у листи.
>> Хајде да погледамо како бисмо могли да дефинишемо струцт за чвор.
А пошто ми желимо да имамо више чворова,
ово ће постати типедеф струцт
у којој ћемо имати неколико различитих инстанци чворова.
И тако смо га дефинишемо као нови тип података.
Ево, имамо типедеф струцт цвор.
У овом примеру, имамо посла са целим чворова,
тако да имамо целобројну вредност по имену, а онда ћемо имати још једну показивача,
и у овом случају, то је показивач на чвор, тако да имамо струцт цвор * зове следећи.
И онда смо називајући целу ову ствар чвор.
Уверите се да пратите ову синтаксу.
Приметимо да чвор заправо упућује горе, као и испод заграда.
Онда да пратите где је мој први чвор је у овој повезаној листи,
онда имам чвор показивач зове глава, а ја маллоц простора довољно за величине чвора.
Приметите, међутим, да је заправо глава чвор показивач за разлику од стварног саме чвор.
Тако је шеф заправо не садржи никакву вредност,
само указује на први чвор год у мојој листи је повезана.
>> Да бисте добили бољи осећај повезаних листи, јер је то веома важно
да пратите и уверите се да сте одржавају ланац,
Волим да мислим о томе како људи у линији држећи се за руке,
где свака особа држи за руке са следеће.
Ви не можете да видите на овом цртежу, али у суштини они указују на следећу особу
који је у свом ланцу.
И тако, ако желите да пролазе повезану листу где су ти људи -
замислити све од тих људи имају вредности повезане са њима
и указати на следеће особе у линији -
ако желите да пролазе повезану листу, на пример, или уређивање вредности
или потрага за вредност или нешто слично,
онда ћете желети да имате показивач на одређену особу.
Тако ћемо имати податке показивач типа чвора.
За овај пример, назовимо га курсор.
Други уобичајени начин да наведемо ово би итератора или нешто слично
зато што је итератинг изнова и стварно креће којој чвор то је указивање на.
Ово овде ће бити наш курсор.
Наш курсор ће прво указати на први елемент у нашој листи.
И тако оно што ми желимо да урадимо је да смо у основи бити наставак курсор,
премештање са једне на другу страну.
У овом случају, желимо да га преместили на следећи елемент у листи.
Са низовима, шта ћемо урадити јесте да само кажемо повећање индекса од 1.
У том случају, оно што треба да урадимо је заправо наћи које лице ове струје особа указује да,
и то ће бити следећи вредност.
Дакле, ако курсор само чвор показивач, онда оно што желимо да урадимо
је да ми желимо да дођемо до вредности која се курсор указује на.
Желимо да се на тај чвор и онда, кад смо у том чвору, наћи тамо где је указујући на.
Да бисте стигли до самог чвора да курсор указује на,
Обично смо га уписати (* курсор).
То ће вам дати стварну чвор да се курсор упућује на.
А онда, након тога, оно што желимо да урадимо јесте желимо да приступите
шта год да следећа вредност чвора је.
Да би то урадили, да бисте приступили вредности унутар струцт, имамо дот оператера.
Онда би било (* курсор) следећи..
Али ово је мало неуредна у смислу да заграде око * курсора,
и тако смо заменили целу ову изјаву са курсор->.
То је црта, а затим већи него знак, тако што стрелу.
курсор-> следеци.
То ће заиста добити вам чвор који се курсор указује. Та вредност је на следећи.
Дакле, уместо да звезду и тачку, ви мењате то са стрелом.
Будите веома пажљиви да се уверите да покушате да користите ову синтаксу.
>> Сада када имамо курсор, ако желимо да приступимо вредност,
раније, имали смо курсор-> нект,
али да приступите вредност на чвору да се курсор упућује да, ми једноставно само реци
чвор-> вредност.
Одатле, то је врста података год смо дефинисали вредности и чворове да буде.
Ако је инт чвор, а затим курсор-> вредност само ће бити цео број.
Дакле, можемо да урадимо операције на то, проверите једнакости, доделити му различите вредности, итд
Па шта онда желите да урадите уколико желите да померите курсор на следећу особу,
Ви заиста променити вредност курсора.
Пошто курсор је чвор показивач, променили сте стварну показивача адресу
на адресу следећег чвора у листи.
Ово је само неки број где сте могли прелазили.
Где сам коментар нешто уради,
то је место где ћете вероватно ћеш да приступите вредности
или уради нешто са том конкретном чвору.
Да бисте га почетак, ја кажем да је мој почетку курсор
ће да укаже на први елемент у повезаној листи.
И тако напред, ја сам га дефинише као шефа чвора.
>> Као што сам раније поменуо, ослобађајући је заиста важно.
Ви желите да се уверите да сте слободни сваки елемент у листи када завршите са њим.
Када не треба да упућују неки од тих показивача више,
желите да се уверите да сте слободни све те показивача.
Али ти желиш да будеш веома пажљив овде у који желите да избегнете било какво цурење меморије.
Ако прерано сте слободни једна особа, онда сви показивача који тај чвор указује на
ће бити изгубљен.
Враћајући се на лицу пример да би се мало више високих улога,
хајде да те људе, осим у овом случају они су лебди изнад језера са чудовиштем.
Желимо да се уверите да кад год смо ослободили, не губимо
и пустите било чворова пре него што смо смо их ослободили.
На пример, ако сте били да једноставно позовете бесплатно на овог момка овде,
онда би се ослободио, али онда сви ови момци ће онда бити изгубљен
и они би нанос искључен и пасти.
Дакле, желимо да се уверите да уместо тога, желимо да одржимо везу са остатком.
Наше главе показивач, који показује на први елемент у листи.
То је као конопац сидрења прву особу.
Оно што можда желите да урадите када сте слободни листа имају -
Ако желите да се прво ослободи први елемент, онда можете имати привремену показивач
који указује на било први елемент је.
Дакле, имате ваша привремена показивач указује овде.
Тако, имамо држи првог чвора.
А онда, пошто знамо да је први чвор ће бити ослобођен,
онда можемо да пређемо тај конопац, ово сидро, наша глава,
да заправо указују на све што први указује на.
Дакле, ово глава заправо указује на другом елементу сада.
Сада нам је дозвољено да ослободи све што се чува у темп,
и тако можемо избрисати да без тога угрожавања свих осталих чворова у нашој листи.
Други начин да то урадите може да буде
сваки пут када само ослободити последњи елемент у листи
јер они гарантовано неће бити указао на било шта.
Значи само да ослободи ово, онда слободно то један, онда слободно то један.
То дефинитивно ради али је мало спорија, јер по природи повезаних листи,
не можемо одмах прећи на последњој.
Морамо да пролазе сваки елемент у повезаној листи
и проверите да ли је неко указује на НУЛЛ, проверите сваки пут,
и онда када стигнемо до краја, онда без тога.
Ако сте били да се овај процес, ви заправо била ту проверу,
провера овде, онда проверу овде, ослобађајући га,
онда враћам, провера овде, провери овде, ослобађајући га,
провере овде, а затим га ослободе.
То траје мало више времена. Да.
>> [Ученик] Да ли је могуће направити листу која складишти повезане излазну показивач до краја?
То би дефинитивно било могуће.
Да поновим питање, могуће је да имате повезану структуру листе
тако да имате показивач указује на крај повезане листе?
Ја бих рекао да је то могуће, и сваки пут када убаците нешто у своју повезану листу
ти би да ажурирате тај показивач и такве ствари.
Ти би имати чвор реп *, на пример.
Али када сте примене ову функцију, морате да мислите о траде-офф,
волим колико пута ћу бити итератинг због тога,
Колико је тешко ће бити да пратите репа као и главу
као и мој Итератор, и такве ствари.
Да ли то -? >> [Ученик] Да.
То је могуће, али у смислу дизајна одлука, морате да одмери опције.
>> Овде је скелет кода који ће вам омогућити да ослободите сваки елемент у повезану листу.
Опет, пошто сам итератинг преко повезаног листи, ја ћу желети да имају неку врсту курсора
или итератор.
Ми смо итератинг док курсор НУЛЛ.
Ви не желите да вршите итерацију када курсор НУЛЛ
јер то значи да не постоји ништа у листи.
Па онда овде направи привремени чвор *
указујући на оно што сам с обзиром је први мојој листи,
и онда сам померим курсор напред 1 и онда слободно све што сам имао у привременом складишту.
>> Сада долазимо до убацивања у повезаним листама.
Имам три чвора у мом повезаном листи, и идемо са једноставном случају
где желимо да убаците другу чвор на крају нашег повезане листе.
Да бисте то урадили, сви ћемо урадити јесте бисмо прешли
да пронађе где се тренутно крај повезан листи је, како год чвор указује на НУЛЛ -
да је ово један -
и онда кажу, у ствари, ово неће бити последњи чвор;
ми заправо ћемо имати још једну.
Тако бисмо имали ову тренутну један бод год смо убацивање.
Тако сада ова црвена особа овде постаје последњи чвор у повезаној листи.
И тако карактеристична за последње чвора у повезаној листи је да указује на НУЛЛ.
Па шта онда бисмо морали да урадите је да подесите показивач Овај црвени момка на НУЛЛ. Ето.
>> Али шта ако бисмо хтели да убаците чвор између другог и трећег један?
Та није баш тако једноставно, јер желимо да будете сигурни
да не пусти било чвора у нашој повезану листу.
Оно што би требало да урадите је да проверите да смо се усидре на сваког од њих.
На пример, назовимо ово други.
Ако сте рекли други сада показује на овом новом
а ви само тамо направили показивач, онда би за последицу овај момак да се изгуби
јер не постоји веза са њим.
Уместо - Ја ћу извући ово поново. Извините моје уметничке способности.
Ми знамо да не можемо једноставно повезати директно 2 на нови.
Морамо бити сигурни да се држимо до последњег.
Оно што можемо да урадимо је да има привремену показивач
да елемент који ће бити придодат даље.
Онда смо се тамо привремено показивач.
Пошто знамо да је ово трећи се чува евиденцију о,
2 сада може повезати на наш нови.
А ако овај нови црвени момак ће бити између 2 и 3,
онда шта је тај тип је показивач ће указати на? >> [Ученик] темп.
Темп. Да.
Онда следећа вредност овом црвеном лик је ће бити темп.
Када убаците у повезаним листама, видели смо да смо могли
лако додати нешто до краја стварањем привремене низ,
или ако смо хтели да додам нешто у сред нашег низу,
онда ће требати мало више меша около.
Ако желите да, на пример, имају сортирани повезану листу,
онда морате да некако вагати трошкова и користи које
јер ако желите да имате сортирани низ, то значи да сваки пут када убаците у њу,
то ће узети мало више времена.
Међутим, ако желите да касније, као што ћемо наћи ћемо желети да,
Тражи кроз повезану листу, онда то може бити лакше ако знате да је све у реду.
Дакле, можда ћете желети да одмери трошкове и користи од тога.
>> Други начин да се унесе у повезаној листи је да убаците у самом почетку листе.
Ако скрећемо овде сидро - то је наша глава -
и онда су ти људи повезани са њим,
и онда имамо нову чвор да се убаци у почетку,
онда шта бисмо могли да радимо?
Шта би било у реду са само кажем да желим да се повежете црвене до плаве,
јер је то први?
Шта би овде десило?
Све ове три би се изгубила.
Дакле, ми не желимо да то урадим.
Опет смо научили да морамо да имамо неку врсту привременог показивача.
Да одлуче да имају привремену тачку на овог момка.
Тада можемо имати плаву један бод на привремени
и онда црвени показивач на плаво.
Разлог зашто ја користим људе овде, јер ми заиста желимо да визуализује
држећи на људе и да се уверите да имамо везу на њих
Пре него што пусти друге стране, или нешто слично томе.
>> Сада када имамо осећај повезаних листи - како бисмо могли створити повезану листу
и створити структуре за које се састоји од типа дефиниције за чвор
и онда да се уверите да имамо показивач на челу тог повезаних листи -
Једном смо да и ми знамо како да прођу кроз низ,
приступите различите елементе, знамо како да убаците и знамо како да их ослободе,
онда можемо ући у правописних грешака.
Као и обично, ми имамо део питања која ће се сте користили за пословање са повезаним листама
и различите структуре, као што су редове и димњацима.
Онда можемо да идемо у правописних грешака.
>> Грешке има у дистрибутивном код неколико досијеа значаја.
Прво смо приметили да овде имамо ову Макефиле,
које нисмо стварно срели раније.
Ако сте гледали унутар псет5 фасцикле, ти би приметити да имате х фајл.,
онда имате две ц фајлове..
Шта ово ради је Макефиле раније, ми бисмо маке а онда име програма
и онда ћемо видети све ове аргументе и заставе усвојен на компајлера.
Шта ради је Макефиле нам омогућава да састави неколико фајлова одједном
и проћи у заставама које желимо.
Овде видимо овде је заглавље датотеке.
Онда ми заправо имамо две изворне фајлове.
Имамо спеллер.ц и дицтионари.ц.
Ви сте добродошли да уредите Макефиле ако желите.
Приметимо да овде ако откуцате чист, онда оно што ради је заправо уклања све
то је језгро.
Ако имаш грешку сегментације, у суштини добијате депонију језгра.
Дакле, ова ружна мала датотека ће се појавити у вашем именику зове језгро.
Ви ћете желети да уклоните да би га чистим.
Она уклања све еке фајлове и о фајлова..
>> Хајде да погледамо у дицтионари.х.
Овај каже да прогласи функционалност речника је.
Имамо максималну дужину за било речи у речнику.
Ми кажемо да ће ово бити најдужи могући реч. То је дужине 45.
Дакле, ми нећемо имати никакве речи које премашују ту дужину.
Овде имамо само функцијских прототипова.
Ми немамо конкретну реализацију, јер то је оно што ћемо радити за ову псет.
Али, шта то ради је јер смо се баве већим фајловима овде
и функционалност у већем обиму, то је корисно имати х фајл.
тако да неко други чита или коришћењем кода може да разуме шта се дешава.
А можда желе да спроведу покушава ако јеси хеш табеле или обрнуто.
Онда бих моју функцију учитавања
стварна реализација ће да се разликују, али то прототип неће променити.
Овде смо проверили, које враћа труе ако дати реч у речнику.
Онда имамо оптерећења, што у основи узима у датотеци речника
и онда га учитава у неку структуру података.
Имамо величину, који, када се зове, враћа величину речника,
колико речи се чувају у њему,
и онда истовара, који ослобађа меморију све које сте преузели
правећи свој речник.
>> Хајде да погледамо дицтионари.ц.
Видимо да то изгледа врло слично дицтионари.х, осим сада има само све ове тодос у њему.
И то је твој посао. На крају, бићете попуњавањем спеллер.ц са свим овим кодом.
Дицтионари.ц, када покренете, није стварно да уради ништа,
па гледамо према спеллер.ц да види стварну примену правописа.
Чак и ако не идеш да се уређивање било овог законика,
важно је да чита, разуме када је оптерећење зове, када сам зове чек,
само да разуме, мапирати га, види како функционише.
Ми видимо да се то провери за правилно коришћење.
У суштини, када неко ради Спеллер, то указује да је опционо
за њих да прође у речнику датотеци јер ће бити подразумевани речник фајл.
И онда они морају да прођу у тексту да се правописа проверава.
русаге бави време, јер део овог псет којима ћемо се бавити касније
није само добијање функционисање спелл-Цхецкер ради
али заправо све да буде брз.
И тако онда то је где русаге ће да уђу
Овде видимо први позив на један од наших дицтионари.ц фајлова, што је оптерећење.
Оптерећење враћа труе или фалсе - тачно на успех, лажни након неуспеха.
Дакле, ако речник није учитан исправно, онда ће се вратити спеллер.ц 1 и отказ.
Али ако се то деси оптерећење правилно, онда ће то наставити.
Настављамо и видимо овде неки фајл И / О,
где ће се суочити са отварањем текстуалну датотеку.
Ево, шта је ово ради је правописа проверава сваку реч у тексту.
Па шта спеллер.ц ради овде се итератинг преко сваке речи у текстуалној датотеци
а затим их провере у речнику.
Ево, имамо Боолеан погрешно написану која ће видети да ли чек врати истина или не.
Ако реч је заправо у речнику, онда провера ће се вратити истина.
То значи да реч није погрешно.
Дакле, погрешно би било погрешно, и то је разлог зашто смо тамо прасак, индикација.
Настављамо да иде, и онда води евиденцију о томе колико погрешно написане речи
постоје у датотеци.
Она се наставља и затвара фајл.
Онда овде, извештава колико погрешно написане речи сте имали.
Она израчунава колико времена је било потребно да се учита речник,
колико времена је било потребно да се провери,
колико времена је било потребно да израчуна величину,
који је, како ћемо ићи даље, треба бити веома мали,
па колико времена је требало да истовари речник.
Овде горе видимо позив да овде истоваре.
Ако бисмо проверили за величину овде,
онда видимо да је овде позив на величину где одређује величину речника.
Страва.
>> Наш задатак за ову псет је да спроведе оптерећења, што ће учитати речник
Структура података - шта год да изаберете, било да је хеш табела или пробајте -
са речима из речника датотеке.
Онда имате величину, која ће вратити број речи у речнику.
А ако спроведе оптерећење у паметан начин, онда величине треба да буде прилично лако.
Онда сте проверили, који ће проверити да ли дата реч налази у речнику.
Тако спеллер.ц пролази у низу, а онда морате да проверите да ли је стринг
садржан у вашем речнику.
Приметите да смо генерално имају стандардне речнике,
али у овом псет, у основи било речник донет на било ком језику.
Дакле, ми не можемо само претпоставити да је Реч је унутра.
Реч Фообар може дефинисати у одређеном речнику који пролазимо ин
А онда смо истовара, који ослобађа речник из меморије.
>> Прво, желео бих да идем у хеш метод табеле
о томе како бисмо могли спровести све те четири функције,
и онда идем преко покушава метод, како можемо имплементирати ове четири функције,
и на крају приче о неким општим савете када правите псет
и како ћете можда бити у могућности да користите Валгринд да проверите за меморијске цурења.
>> Идемо у хеш табеле методом.
Хасх табела се састоји од листе корпи.
Свака вредност, свака реч, је да идем у једну од ових сегмената.
Хасх табела идеално равномерно распоређује свим овим вредностима које сте пролазу у
а затим их попуњава у кофи том што свака кашика
има око једнаким бројем вредности у њему.
Структура за хеш табели, имамо низ повезаних листи.
Шта радимо када прођемо у вредности, ми смо проверили где је вредност треба да припадају,
која кашика припада, а затим га ставите у повезаној листи повезан са том кашиком.
Ево, шта ја имам је хеш функција.
То је инт хасх табели.
Дакле, за прву кофу, сви цели бројеви испод 10 иде у прву кофу.
Било целих изнад 10, али испод 20 иду у други,
и онда тако даље и тако даље.
За мене, свака кашика заступа ове бројеве.
Ипак, кажу да је требало да прође у 50, на пример.
Изгледа као да је прва три садржи низ од десет бројева.
Али ја желим да дозволите ми хеш табела да се у било којој врсти целих бројева,
па онда би морао да филтрира све бројеве изнад 30 у последњој кофу.
И тако онда би резултирати неком врстом неуравнотеженом хеш табеле.
Да подсетимо, хеш табела је само низ сегмената
где је сваки кофа повезана листа.
И тако би се утврдило где свака вредност иде, која кашика иде у,
ћеш да желим оно што се зове хеш функција
који узима вредност и онда каже ова вредност одговара одређеном корпе.
Дакле, горе у овом примеру, мој хасх функција је сваку вредност.
Она проверава да ли је било мање од 10 година.
Ако јесте, то би га ставио у први кофу.
Она проверава да ли је мање од 20, ставља га у други ако је то тачно,
проверава да ли је мање од 30 година, а затим га ставља у трећем кофу,
и онда све остало само пада на четврту корпе.
Дакле, кад год имате неку вредност, ваш хеш функција
ће ставити ту вредност у одговарајуће корпе.
Хеш функција у основи треба да зна колико кашике имате.
Ваша хасх табела величине, број корпи имате,
то ће бити фиксни број који је до вас, за вас да одлучите,
али то ће бити фиксни број.
Дакле, ваша хасх функција ће се ослањати на то да се утврди које кашика сваки тастер иде у
таква да је равномерно распоређена.
Слично нашем имплементацију повезаних листи, сада сваки чвор у хеш табели
заправо ће имати знак типа.
Дакле, имамо низ цхар називом реч, а затим још један показивач на следећи чвор,
што има смисла, јер ће то бити повезана листа.
Сећаш ли се када смо повезани листе, направио сам чвор * зове глава
који је указујући на први чвор у повезаној листи.
Али за наше хеш табеле, јер имамо више повезаних листи,
оно што ми желимо је да желимо наш хеш табела бити као, "Шта је канта?"
Кашика је само списак чвора показивача,
и тако сваки елемент у кофи заправо указује на одговарајућој повезаних листи.
Да се ​​вратимо на ову шему, видећете да су сами кашике су стрелице,
не стварни чворова.
Један од суштинског значаја имовина хеш функција је да су детерминистичка.
То значи да кад год хеш број 2,
увек треба да врати исту канту.
Свака појединачна вредност која иде у хеш функцију, ако се понови,
има да добије исти индекс.
Дакле, ваш хасх функција враћа индекс низа
где је вредност припада.
Као што сам раније поменуо, број корпи је фиксна,
и тако ваш индекс који се вратите мора да буде мањи од броја сегмената
али већи од 0.
Разлог зашто смо хеш функције уместо само једним повезану листу
или једна низ је да ми желимо да будемо у стању да скочи на одређени одељак најлакше
ако знамо својство вредности -
уместо да тражи кроз цео цео речник,
бити у стању да пређете на одређеном делу њега.
Ваша хеш функција треба да узме у обзир да у идеалном случају,
свака кашика има приближно исти број тастера.
Пошто је хасх табела низ повезаних листи,
онда повезани сами спискови ће имати више од једног чвора.
У претходном примеру, две различите бројеве, чак иако они нису били једнаки,
када хеширају, враћали исти индекс.
Дакле, када се баве речима, једну реч када хеширају
ће бити исти хеш вредност као друге речи.
То је оно што ми зовемо судара, када имамо чвор који, када хеширане,
повезана листа у том кофи није празан.
Техника коју зовемо постоји линеарна прескок,
где идете на повезану листу, а затим пронађите где желите да убаците тај чвор
јер имате судар.
Можете видети да можда постоји траде-офф овде, зар не?
Ако имате веома мали хеш табелу, веома мали број корпи,
онда ћеш имати много судара.
Али онда ако направите веома велики хеш табелу,
вероватно ћеш да минимизира судара,
али то ће бити веома велика структура података.
Ту ће бити компромиси са тим.
Дакле, када правите свој псет, покушајте да играте
између можда што мањи хеш табелу
али онда знајући да ће то узети мало више времена да прођу различите елементе
тих повезаних листи.
>> Шта оптерећење ће да уради јесте прелазили преко сваке речи у речнику.
Она пролази у показивач на речника фајл.
Тако ћеш да искористе датотеке И / О функције које сте усавршили у псет4
и прелазили преко сваку реч у речнику.
Хоћеш сваку реч у речнику да постане нови чвор,
и ти ћеш ставити сваки од ових чворова унутар структуре вашег речника података.
Кад год добијете нову реч, ви знате да ће то постати чвор.
Дакле, можете одмах отићи и маллоц показивач чвор за сваку нову реч коју имате.
Ево зовем моју чвор показивача нев_ноде и ја маллоцинг шта? Величина чвора.
Онда да прочитате стварни стринг из фајла, јер је речник заправо чувају
од речи и онда нови ред, шта можемо искористити
је функција фсцанф,
при чему фајл је речник фајл који смо прошли у,
тако да скенира фајл за ниску и места која стринг у последњи аргумент.
Ако се вратите сећате једног од предавања, када смо отишли ​​у
и врста ољуштен слојеве назад на ЦС50 библиотеке,
Видели смо да је спровођење фсцанф.
Да се ​​вратимо на фсцанф, имамо датотеку да читате,
тражимо ниску у том фајлу, и онда смо га ставља у
Овде имам нев_ноде-> рец, јер нев_ноде је чвор показивач,
Није стварна чвор.
Онда ја кажем нев_ноде, желим да идем у чвор да се то указује на
и онда доделите ту вредност речи.
Желимо да онда узети ту реч и убаците га у хеш табелу.
Схватите да смо направили нев_ноде чвор показивач
јер ћемо желети да знају шта адресу тог чвора је
када смо га убацили у, јер је структура самих чворова, од струцт,
је да они имају показивач на нови чвор.
Па у чему је онда адреса тог чвора ће указати на?
Та адреса ће бити нев_ноде.
Да ли то има смисла, зашто чинимо нев_ноде а * чвор насупрот чвор?
Ок.
Имамо реч. Та вредност је нев_ноде-> рец.
Који садржи реч из речника који желимо да улаз.
Дакле, оно што ми желимо да урадимо јесте желимо да позовете наш хеш функцију у том низу
јер је наш хасх функција узима у низу, а онда се враћа нам цео број,
где је цео је индекс где Хасхтабле на том индексу представља ту канту.
Желимо да тај индекс, а затим идите на том индексу хеш табеле
и онда користите ту повезану листу да убаците чвор на нев_ноде.
Запамтите да ипак одлучите да убаците чвор,
да ли је у средини ако желите да га сортирате
или на почетку или на крају, само проверите да ли ваш последњи чвор увек указује на НУЛЛ
јер то је једини начин на који знамо где је последњи елемент нашег повезаних листи је.
>> Ако је величина цео број који представља број речи у речнику,
онда један од начина да то урадите је да кад год се зове величина
идемо кроз сваки елемент у нашој хасх табеле
а онда прелазили преко сваког повезаног листе у року од хеш табели
и онда израчунати дужину да повећава нашу противтужбу 1 од 1.
Али сваки пут када се зове величина, који ће трајати дуго времена
јер ћемо бити линеарно сондирање сваку повезану листу.
Уместо тога, то ће бити много лакше ако пратите колико речи су прошли ин
Дакле, ако сте укључити бројач унутар ваше оптерећења функцији
која се ажурира по потреби, онда контра, ако га поставите на глобална променљива,
ће моћи да се приступи по величини.
Дакле, шта величине може једноставно урадити у једној линији, само вратите контра вредност,
на величину речника, коју већ бавили у оптерећењем.
То је оно што сам мислио када сам рекао ако спроведе оптерећење на користан начин,
онда величина ће бити прилично лако.
>> Дакле, сада смо добили да проверите.
Сада имамо посла са речима из датотеке унос текста,
па ћемо да провере да ли је све те речи улазних
су заправо у речнику или не.
Слично сцрамбле, желимо да омогући случај неосетљивости.
Ви желите да се уверите да све речи донет, иако су мешовити случај,
када се позове са гудачким упоредите су еквивалентна.
Речи у датотекама речника текстуалних су заправо сви малим словима.
Друга ствар је да можете претпоставити да је свака реч донет, сваки стринг,
ће бити или алфабетски или садрже апострофа.
Апострофа ће бити валидне речи у нашем речнику.
Дакле, ако имате реч са апострофом С, то је стварна легитимна реч у вашем речнику
то ће бити један од чворова у вашем хеш табели.
Проверите да ли послује са реч постоји, онда то мора да буде у нашем хеш табели.
Ако је реч у речнику, онда све речи у речнику су у хеш табели,
па хајде да погледамо овај речи у хеш табели.
Ми знамо да пошто смо имплементирали наше хеш функцију
таква да је свака јединствена реч увек хеширају истом вредношћу,
онда знамо да уместо трагања кроз читаву нашу целу хеш табели,
ми заправо можемо да нађемо повезану листу да та реч припада.
Ако је то у речнику, онда би у том канту.
Оно што можемо да урадимо, ако је реч име наше ниске усвојен у,
можемо само да хасх реч и поглед на повезану листу
у вредности од Хасхтабле [хеш (реч)].
Одатле, шта можемо да урадимо је да имамо мањи подскуп чворова за претрагу за ову реч,
па можемо прећи повезану листу, користећи пример из раније у објашњења,
а затим позива стринг упореди по реч где год курсор указује да,
та реч, и видети да ли они поредити.
У зависности од начина да организујете своје хеш функцију,
ако је сортиран, можда ћете моћи да се врати лажно мало раније,
али ако је то некласификовани, онда желите да наставите попречно кроз повезану листу
док вам је последњи елемент листе.
А ако још увек нисте нашли реч време које сте постигли крај повезану листу,
то значи да твоја реч не постоји у речнику,
па та реч је неважећа,
и провера треба да се врате лажна.
>> Сада долазимо до истовара, где желимо да ослободимо свих тачака које смо маллоц'д,
па без свих тачака унутар нашег хеш табели.
Ми ћемо желети да вршите итерацију над свим повезаним листама и без свих чворова у то.
Ако погледате горе у објашњења за пример где смо ослободили повезану листу,
онда ћете желети да понови тај процес за сваки елемент у хеш табели.
А ја ћу због овога на крају објашњења,
али Валгринд је алат где можете видети да ли сте правилно ослободио
сваки чвор који сте маллоц'д или било шта друго што сте маллоц'д, свака друга показивач.
Дакле, то је хеш табеле, где имамо ограничен број сегмената
и хасх функција која ће се вредност, а затим доделите ту вредност на одређени корпе.
>> Сада долазимо до покушаја.
Покушава врсте изгледа овако, и ја ћу извући пример.
У суштини, имате читав низ потенцијалних писама,
и онда кад ти изградње реч,
то писмо може бити повезан на речнику на широк спектар могућности.
Неке речи почињу са Ц, али онда настави са,
али други настављају са О, на пример.
Трие је начин визуелно свих могућих комбинација тих речи.
Трие ће пратити низа писама које чине речи,
Гранање се када је то потребно, када се једно слово бити праћено умножак писама,
и на крају показују у сваком тренутку да ли је реч важи или не
јер ако сте правопис реч МАТ МА ја не мислим да је важећа реч, али је МАТ.
И тако у трие, то би значило да након МАТ то је заправо важи реч.
Сваки чвор у нашем трие се заправо дешава да садржи низ показивача чвора,
и ми ћемо морати, конкретно, 27 тих чвора показивача,
један за свако писмо у писму, као и апостроф карактера.
Сваки елемент у том низу је и сама ће да укаже на други чвор.
Дакле, ако је чвор је НУЛЛ, ако нема ништа после тога,
онда знамо да нема никаквих даљих слова у тој речи низу.
Али ако тај чвор није НУЛЛ, то значи да постоји више слова у том писму низу.
А онда даље, сваки чвор означава да ли је то последњи знак речи или не.
>> Идемо у један пример трие.
Прво морам собу за 27 чворова у овом низу.
Ако имам реч Бар -
Ако имам реч БАР и желим да убаците да,
прво слово Б, па ако ми трие је празна,
Б је друго слово азбуке, тако да ћу изабрати да ставим овде на овом индексу.
Ја ћу морати Б овде.
Б ће бити чвор који указује на неки други низ свих могућих ликова
да прати након писма Б.
У овом случају, ја сам се баве речи БАР, па ће овде иде.
После, имам писмо Р, па онда се сада показује на свом комбинацији,
и онда Р ће бити овде.
БАР је комплетна реч, па онда ћу морати Р тачку на другом чвору
која каже да је реч је важећи.
Тај чвор је такође ће имати низ чворова,
али они могу бити НУЛЛ.
Али у суштини, она може да настави овако.
То ће постати мало јасније кад одемо у другу пример,
па само носе са мном тамо.
Сада имамо БАР унутар наше речнику.
Сада кажу да имамо реч Баз.
Почињемо са Б, а ми већ имамо Б као једном од писама које је у нашем речнику.
То је праћено А. Имамо већ.
Али онда уместо тога, имамо З следеће.
Дакле елемент у нашој низу ће бити З
па онда да је један ће указати на другу важећу крају речи.
Дакле, видимо да, када ћемо наставити кроз Б, а затим,
постоје две различите опције тренутно у нашем речнику за речи које почињу са Б и А.
Реци ми смо желели да убаците Фообар реч.
Тада ћемо направити унос у Ф.
Ф је чвор који указује на читав низ.
Ми бисмо пронашли О, идите на О, о онда повезује на целу листу.
Имали бисмо Б и онда наставите, имали бисмо и онда Р.
Дакле Фообар прелази скроз доле док Фообар је исправна реч.
И тако онда ће то бити валидан реч.
Сада кажу да наш следећи реч у речнику је заправо реч ФОО.
Ми бисмо рекли Ф. Оно што следи Ф?
Ја заправо већ имам простора за О, па ћу наставити.
Не треба да се направи нови. Настави.
ФОО је важећа реч у овом речнику, па онда ћу да укаже
да је то исправан.
Ако сам зауставити свој редослед, то би било тачно.
Али, ако смо наставили наш секвенцу од Фоо до Б
и само је ФООБ, ФООБ није реч, а то није наведено као важећег.
У трие, ви сте сваки чвор указује да ли је валидна реч или не,
и онда сваки чвор има низ од 27 чвора показивачи
да онда указују на чворове самих.
>> Овде је начин како ћете можда желети да дефинишете.
Међутим, баш као у хеш табели пример, где смо имали чвор * главу
да укаже на почетак нашег повезану листу, такође ћемо желети
неки начин знајући где почетак нашег трие је.
Неки људи позив покушава дрвеће, а то је место где корен долази.
Дакле, ми желимо корен нашег стабла до уверите се да ћемо остати утемељено
где год је наш трие је.
Ми смо већ некако прешли
начин можете да размислите о утовар сваку реч у речнику.
У суштини, за сваку реч коју ћеш желети да вршите итерацију кроз трие
и знајући да је сваки елемент у деце - звали смо га деца у овом случају -
одговара другом писму, ти ћеш желети да провери те вредности
у том индексу који одговара на писмо.
Тако размишља скроз назад на Цезара и Вигенере,
знајући да је свако слово можете некако мапи назад на азбучном индекс,
Дефинитивно до З ће бити прилично лако мапирати на азбучном писму,
али, нажалост, апострофа су прихваћена лик у речима.
Нисам чак ни сигуран шта је АСЦИИ вредност је,
па за то ако желите да пронађете индекс да одлучи да ли желите да буде или први
или последњи, мораћете да направите фиксирана чек за то
и онда стави да је у индексу 26, на пример.
Па онда се проверава вредност код деце [и]
где [и] одговара на било писмо сте.
Ако је то НУЛЛ, то значи да не постоји тренутно евентуалне слова
проистичу из тог претходног низу, тако да ћете желети да маллоц
и направити нови чвор и има да деца [и] указују на то
тако да стварају - када смо убаци писмо у правоугаоник -
прављење деце нису НУЛЛ и тачка у том новом чвору.
Али, ако то није НУЛЛ, као у нашем инстанци Фоо
кад смо већ имали Фообар, настављамо,
а ми не никада израду новог чвор већ само постављањем ис_ворд на истина
на крају те речи.
>> Дакле, тада као и раније, јер овде имате посла са сваким словом у једном тренутку,
то ће бити лакше за вас величини, уместо да се израчуна
и пролазе кроз целу дрвета и израчунати колико деце имам
и онда гранања искључен, сећајући се колико су на левој страни и на десној страни
и такве ствари, то ће бити много лакше за вас
ако само пратите колико речи коју додајете у
када имате посла са оптерећењем.
И тако онда тај начин величина може само врати глобалну променљиву величину.
>> Сада долазимо да проверите.
Исти стандарди као пре, где желимо да омогући случај неосетљивости.
Као, ми претпостављамо да су жице су само по азбучном карактера или су апострофа
јер деца је низ од 27 дуго,
па све слова алфабета плус апостроф.
За проверите шта ћете желети да урадите је да ћете желети да почне у корену
јер корен ће указати на низ који садржи
свим могућим почетних слова речи.
Идеш тамо почети,
и онда ћеш да проверите је ова вредност НУЛЛ или не,
јер ако је вредност НУЛЛ, то значи да се речник нема никакве вредности
који садрже то слово у том редоследу.
Ако је НУЛЛ, онда то значи да је реч погрешно одмах.
Али ако то није НУЛЛ, онда можете да наставите,
кажу да је прво слово могуће прво слово у речи,
па сада желим да проверим да ли друго писмо, да је секвенца, је у мом речнику.
Тако ћеш да идеш на индекс деце из првог чвора
и проверите да ли је друго писмо постоји.
Затим поновите тај поступак да провери да ли је редослед важи или не
у вашој трие.
Кад год чворова деца у том индексних поена на НУЛЛ,
знате да редослед не постоји,
али онда ако дођете на крај речи које сте инпуттед,
онда желите да проверите да ли сада сам завршио ову секвенцу
и да га нашао у мојој трие, да је реч важи или не?
И тако онда желите да проверите да ли и тада, ако сте нашли да је редослед,
онда желите да проверите да ли је реч важи или не
јер сетите назад у претходном случају који сам нацртао, где смо имали ФООБ,
који је био валидан секвенца коју смо нашли, али није стварна важи сама реч.
>> Слично томе, за истовар у покушаја желите да истовари све чворова у вашем трие.
Извините. Слично хеш табеле где истоваре смо ослобођени свих чворова,
у покушаја желимо да се ослободимо свих чворова.
Истовар ће заправо радити најлакше од дна до врха
јер су у суштини повезане листе.
Дакле, желимо да се уверите да се држимо све вредности
и без свих њих експлицитно.
Шта ћеш желети да урадите ако радите са трие
је да путује до дна и слободног најнижи могући НОДЕ први
и онда иде до свих тих деце, а затим без свих оних,
иди горе и онда бесплатно, итд
Нешто попут бави доњем слоју трие прво
и онда иде до врха када сте ослобођени све.
Ово је добар пример где рекурзивна функција би могла да дође у руци.
Када ослободио доњи слој вашег трие,
онда зовете истоваре на остатак ње,
пазећи да ослободи сваке мини -
Можете да замислите врста је као мини покушаја.
Дакле, имате овде свој корен.
Само сам га поједностављујући тако да не морам да скренем 26 од њих.
Дакле, имате ово, а онда они представљају низове речи
где су сви од ових малих кругова су писма која важе низови слова.
Идемо даље само мало више.
Шта ћеш желети да урадите је слободан доњи овде и онда слободно ово
и онда слободно ово на дну пре него што се ослободи горњу један овде
јер ако вас нешто бесплатно у другом нивоу овде,
онда би заиста овде губи ову вредност.
Зато је важно у истовари за трие како би били сигурни да сте слободни прво дно.
Оно што можда желите да урадите је рећи за сваки чвор
Желим да истовари све деце.
>> Сада када смо прошли током истовара за хеш табеле методу као и трие метод,
ћемо желети да погледате Валгринд.
Валгринд наиђете са следећим командама.
Имате Валгринд-В.
Ти провера за све цури када покренете Спеллер дао овај текст сигурно
јер буквар треба да узме у текстуалној датотеци.
Тако Валгринд ће покренути ваш програм, да вам кажем колико бајтова си издвојила,
колико бајтова си ослобођен, а он ће вам рећи да ли сте довољно ослобођен
или да нисте слободни довољно,
или понекад можете чак превише слободно, као слободан чвор који је већ ослобођен
и тако ће вам вратити грешке.
Ако користите Валгринд, то ће вам дати неке поруке
указујући да ли сте или ослобођен мање него довољно, сасвим довољно,
или више него довољно времена.
>> Део овог псет, то је опционо да оспори Тхе Биг одбор.
Али када се бавимо овим структурама података
то је некако забавно да види колико брзо и колико ефикасно да ваше структуре података бити.
Да ли ваш хасх функција резултат у много судара?
Или је ваша величина подаци стварно велика?
Да ли је потребно доста времена да прођу?
У дневнику Спеллер, она излази колико времена се користи за учитавање,
да проверите да спроведе величину, и да истовари,
па они су послали у Тхе Биг одбора,
где можете такмичити против својих другара
и неки чланови особља да видимо ко има најбржи провере правописа.
Једна ствар коју бих желео да напоменути о хеш табеле
је да постоје неке прилично једноставне хеш функције које смо могли замислити.
На пример, имате 26 канте, па сваки кашика
одговара првом слову у речи,
али да ће то довести у прилично неуравнотеженог хеш табели
јер постоји много мање речи које почињу са Кс од почетка са М, на пример.
Један од начина да се о Спеллер је ако желите да добијете све друге функционалности доле,
онда само користити једноставне хеш функцију да бисте могли да добијете ваш код ради
и онда се вратите и мењају величину хеш табеле и дефинисање.
Постоји много ресурса на интернету за хеш функције,
па за ову псет вам је дозвољено да истражују хеш функције на Интернету
за неке савете и инспирацију све док се уверите да наведу где сте га добили од.
Ви сте добродошли да погледате и интерпретира неке хасх функцију коју ћете наћи на Интернету.
Назад на то, можда ћете моћи да видите да ли је неко користио трие
да ли је њихово спровођење је брже од хасх табеле или не.
Можете да поднесе Тхе Биг одбор више пута.
Она ће снимити свој најновији унос.
Дакле, можда сте променили своје хеш функцију и онда схвате да је то заправо много брже
или много спорије него раније.
То је помало забаван начин.
Увек има 1 или 2 члана особља који покушавају да направе најспорији могући речник,
тако да је увек забавно гледати.
>> Употреба за псет је да покренете Спеллер са опционим речника
и онда обавезно текст фајл.
Уобичајено је да када покренете Спеллер са само текст фајла, а не одредите речник,
то ће користити датотеку речника текста, велики један
у цс50/псет5/дицтионариес фасцикли.
Тај има преко 100.000 речи.
Они такође имају малу речник који има знатно мање речи
да ЦС50 је направио за тебе.
Међутим, можете врло лако само да свој речник
Ако желите само да се ради у малим примерима -
На пример, ако желите да користите ГДБ и знате конкретне вредности
да желите да се ваш хеш табела мапирати на.
Дакле, можете само да направите сопствену текстуални фајл само са БАР, Баз, Фоо и Фообар,
чине да се у текстуалној датотеци, одвојите оне свака са 1 линијом,
и онда направите сопствену текстуални фајл који садржи буквално само мозда 1 или 2 речи
тако да знате тачно шта излаз треба да буде.
Неке од датотека узорак текста који ће Биг одбор када покренете изазов проверите
Рат и мир су и роман Џејн Остин, или нешто слично томе.
Дакле, када сте почетник, то је много лакше направити сопствене текстуалне датотеке
који садржи само неколико речи, или можда 10
тако да можете предвидети шта исход би требало да буде
и онда провери против тога, тако да више од контролисаног пример.
И тако, јер се бавимо предвиђању и цртање ствари око себе,
Поново желим да вас охрабри да користите оловку и папир
јер заиста ће ти помоћи са овим -
цртање стрелице, како хеш табела или како ваша трие изгледа,
када сте ослобађање нешто где стрелице се дешава,
ви држите на довољно, да ли видите неке везе нестају
и пада у амбис процурио меморије.
Зато вас молим, покушајте да се скрене ствари чак и пре него што дођете до писања кода доле.
Жреб ствари, тако да сте схватили како ствари иду на посао
јер онда ја гарантујем да ћете налетети на мање показивач муддлес тамо.
>> У реду.
Желим да вам пожелим много среће са овом псет.
То је вероватно најтежи један.
Дакле, покушајте да покренете рано, цртање ствари, цртају ствари, и добре среће.
Ово је Валктхроугх 5.
>> [ЦС50.ТВ]