[Powered by Google Translate] [Walkthrough - Masalah Set 5]
[Zamyla Chan - Universiti Harvard]
[Ini adalah CS50. - CS50.TV]
>> Semua hak. Hello, semua orang, dan mengalu-alukan ke 5 Walkthrough.
>> Pset5 adalah salah ejaan, di mana kita akan membuat pemeriksa ejaan.
Ejaan dam adalah amat penting.
Adakah ini pernah berlaku kepada anda?
Anda bekerja sangat, sangat simpan pada kertas untuk pertembungan
dan kemudian masih akhirnya mendapat rade cahaya sangat seperti D atau D =
dan semua kerana anda adalah spoiler sosis yg mengandung cincangan dalam perkataan paus luas.
Ya, proofreading lada anda adalah satu perkara, mati pucuk penuh.
Ini adalah masalah yang menjejaskan waras, pelajar waras.
Saya pernah diberitahu oleh penyiksa gred sith saya bahawa saya tidak akan masuk ke dalam rakan sekerja yang baik.
Dan itu semua yang pernah saya mahu, itu semua mana-mana kanak-kanak mahu pada usia saya,
hanya untuk masuk ke dalam rakan sekerja yang baik.
Dan bukan sahaja mana-mana rakan sekerja. Saya mahu pergi kepada rakan sekerja Ivory satu undang-undang.
Jadi jika saya tidak penambahbaikan, pergi akan menjadi impian saya pergi ke Harvard,
Jale, atau Penjara - anda tahu, di Penjara New Jersey.
Jadi saya mendapat diri saya pemeriksa ejaan.
Itulah petikan sedikit dari salah satu artis perkataan kegemaran saya bercakap, Taylor Mali.
Bagaimanapun, seperti katanya, kepentingan mempunyai ejaan pemeriksa adalah sangat penting.
>> Jadi dialu-alukan untuk 5 Walkthrough, di mana kita akan bercakap tentang pset5: salah ejaan,
di mana kita akan membuat kita sendiri ejaan pemeriksa.
Toolbox untuk minggu ini, kod pengedaran, akan menjadi penting untuk melihat
hanya untuk memahami fungsi yang berbeza yang kamus anda akan mempunyai.
Kami sebenarnya akan mempunyai pelbagai c fail yang bersama-sama membuat pset kami.
Dan sebagainya mencari melalui aspek-aspek yang berbeza, walaupun kita sebenarnya tidak menyunting
salah satu fail, speller.c, mengetahui bagaimana ia berfungsi dengan berhubung dengan dictionary.c,
yang kita akan menulis, akan menjadi cukup penting.
Spec pset juga mengandungi banyak maklumat yang berguna
dari segi perkara yang anda boleh menganggap, peraturan dan perkara-perkara seperti itu,
jadi pastikan untuk membaca spec pset teliti bagi tips.
Dan apabila keraguan peraturan atau sesuatu seperti itu, maka sentiasa merujuk kepada spesifikasi pset
atau Bincangkan.
Pset ini akan banyak bergantung pada petunjuk,
jadi kami mahu memastikan bahawa kita memahami perbezaan antara bintang menambah
di hadapan nama dan penunjuk ampersands, bagaimana untuk membebaskan mereka, dan lain-lain
Jadi, menjadi tuan petunjuk akan menjadi sangat membantu dalam set masalah ini.
Kami akan meneliti senarai berkaitan sedikit lebih,
di mana kita mempunyai unsur-unsur yang kita panggil nod yang mempunyai kedua-dua nilai serta penunjuk
ke nod seterusnya, dan sebagainya dasarnya menghubungkan unsur-unsur yang berbeza salah satu selepas yang lain.
Terdapat beberapa pilihan yang berbeza melaksanakan kamus sebenar anda.
Kami akan melihat kepada dua kaedah utama, yang adalah jadual hash dan kemudian cuba.
Dalam kedua-dua mereka, mereka melibatkan beberapa jenis tanggapan senarai berkaitan
di mana anda telah elemen dikaitkan antara satu sama lain.
Dan jadi kita akan melihat bagaimana anda mungkin tidak dapat beroperasi di sekitar senarai dikaitkan,
mencipta mereka, mengemudi dari segi bagaimana untuk, misalnya, memasukkan nod ke dalamnya
atau percuma di nod serta.
Dari segi nod membebaskan, yang benar-benar penting
bahawa apabila kita malloc ingatan, selepas itu kita membebaskannya.
Jadi kita mahu pastikan bahawa penunjuk tidak pergi unfreed, bahawa kita tidak mempunyai sebarang kebocoran memori.
Kami akan memperkenalkan alat dipanggil Valgrind yang menjalankan program anda
dan cek sama ada semua memori yang anda memperuntukkan kemudian dibebaskan.
Pset anda hanya melengkapkan apabila ia berfungsi dan ia mempunyai kefungsian penuh,
tetapi juga, Valgrind memberitahu anda bahawa anda tidak menemui sebarang kebocoran memori.
Akhirnya, bagi pset ini, saya benar-benar ingin tekankan -
Maksud saya, seperti biasa, saya pasti penyokong menggunakan pen dan kertas untuk set masalah anda,
tetapi untuk yang satu ini, saya berfikir bahawa pen dan kertas akan menjadi penting terutamanya
apabila anda mahu lukisan anak panah untuk perkara dan memahami bagaimana ia berfungsi.
Jadi pasti cuba untuk menggunakan pen dan kertas untuk menarik perkara-perkara yang keluar sebelum anda mendapat kod
kerana ia boleh mendapatkan sedikit kotor.
>> Pertama, mari kita pergi ke senarai berkaitan sedikit.
Berkaitan senarai terdiri daripada nod, di mana setiap nod mempunyai nilai yang dikaitkan dengannya,
serta penunjuk kepada nod berikutnya selepas ia.
Beberapa perkara penting dengan senarai yang dikaitkan adalah bahawa kita perlu ingat
mana nod pertama kami adalah, dan kemudian apabila kita tahu di mana nod pertama adalah,
yang cara kita boleh mengakses nod nod mata pertama untuk
dan kemudian selepas itu dan satu selepas itu.
Dan kemudian elemen terakhir dalam senarai dikaitkan anda adalah penunjuk bahawa nod
sentiasa akan menunjukkan kepada NULL.
Apabila titik nod batal, maka anda tahu bahawa anda telah sampai ke penghujung senarai,
bahawa nod tersebut adalah yang terakhir, bahawa tiada apa-apa selepas itu.
Sini dalam skema ini, anda melihat bahawa anak panah adalah petunjuk,
dan seksyen biru di mana nilai disimpan,
dan kemudian kotak merah dengan penunjuk ia adalah penunjuk nod
menunjuk kepada nod berikutnya selepas ia.
Dan sebagainya yang anda lihat di sini, nod D akan menunjukkan NULL kerana ia adalah elemen terakhir dalam senarai.
>> Mari kita melihat bagaimana kita boleh menentukan struct nod.
Dan kerana kita mahu mempunyai pelbagai nod,
ini akan menjadi struct typedef
di mana kita akan mempunyai keadaan yang berbeza beberapa nod.
Dan supaya kita menentukan ia sebagai jenis data baru.
Di sini, kita mempunyai nod struct typedef.
Dalam contoh ini, kita sedang berurusan dengan nod integer,
jadi kita mempunyai nilai integer yang dinamakan dan kemudian kita mempunyai penunjuk lain,
dan dalam kes ini, ia adalah penunjuk kepada nod, jadi kita mempunyai nod struct * dipanggil seterusnya.
Dan kemudian kita memanggil ini nod segala-galanya.
Pastikan bahawa anda mengikuti sintaks ini.
Perhatikan bahawa nod sebenarnya dirujuk atas serta bawah pendakap kerinting.
Kemudian untuk menjejaki di mana nod pertama saya adalah dalam senarai ini dipautkan,
maka saya mempunyai penunjuk nod dipanggil kepala, dan saya malloc ruang cukup untuk saiz nod.
Notis, bagaimanapun, ketua yang sebenarnya adalah penunjuk nod berbanding kepada nod sebenar itu sendiri.
Jadi kepala sebenarnya tidak mengandungi sebarang nilai,
ia hanya mata kepada mana-mana nod pertama dalam senarai saya dikaitkan.
>> Untuk mendapatkan rasa yang lebih baik senarai yang dipautkan, kerana ia amat penting
untuk menjejaki memastikan bahawa anda mengekalkan rantaian,
Saya suka untuk memikirkan ia sebagai rakyat dalam satu barisan berpegangan tangan,
di mana setiap orang berpegangan tangan dengan satu depan.
Anda tidak boleh melihat dalam lukisan ini, tetapi pada dasarnya mereka menunjuk kepada orang yang seterusnya
yang dalam rantaian mereka.
Dan jadi jika anda mahu merentasi senarai berpaut di mana orang-orang ini -
bayangkan semua orang mempunyai nilai-nilai yang dikaitkan dengan mereka
dan juga menunjukkan kepada orang yang seterusnya dalam baris -
jika anda mahu melintasi senarai berkaitan, misalnya, sama ada untuk mengedit nilai
atau mencari nilai atau sesuatu seperti itu,
maka anda akan mahu mempunyai penunjuk kepada orang yang tertentu.
Jadi, kita akan mempunyai jenis data penunjuk nod.
Sebagai contoh ini, mari kita memanggilnya kursor.
Satu lagi cara yang biasa untuk menamakan ini akan iterator atau sesuatu seperti itu
kerana ia iterating alih dan sebenarnya bergerak nod yang ia menunjuk ke.
Ini di sini akan kursor kami.
Kursor pertama kami akan menunjukkan kepada elemen pertama dalam senarai kami.
Dan jadi apa yang kita mahu lakukan ialah kita pada dasarnya akan meneruskan kursor,
bergerak dari sisi ke sisi.
Dalam kes ini, kita mahu memindahkannya ke elemen seterusnya dalam senarai.
Dengan tatasusunan, apa yang kita akan lakukan ialah kita hanya akan mengatakan bahawa kita meningkatkan indeks oleh 1.
Dalam kes ini, apa yang perlu kita lakukan adalah sebenarnya mencari yang orang orang ini semasa menunjuk ke,
dan yang akan menjadi nilai seterusnya.
Jadi jika kursor hanya penunjuk nod, maka apa yang kita mahu lakukan
ialah kita mahu mendapatkan nilai yang kursor menunjuk ke.
Kita mahu mendapatkan nod tersebut dan kemudian, apabila kita berada di nod tersebut, mencari di mana ia menunjuk ke.
Untuk mendapatkan ke nod sebenar bahawa kursor menunjuk ke,
biasanya kita menunjukkan bahawa ia oleh (* kursor).
Yang akan memberi anda nod sebenar bahawa kursor menunjuk ke.
Dan kemudian selepas itu, apa yang kita mahu lakukan ialah kita mahu untuk mengakses
apa yang nilai nod seterusnya.
Untuk berbuat demikian, untuk mengakses nilai dalam struct itu, kita mempunyai pengendali dot.
Jadi maka ia akan menjadi (* kursor). Seterusnya.
Tetapi ini adalah sedikit kotor dari segi mempunyai kurungan sekitar kursor *,
dan sebagainya kita menggantikan keseluruhan kenyataan ini dengan kursor->.
Ini adalah melontarkan dan kemudian satu tanda yang lebih besar daripada, jadi membuat anak panah.
kursor-> seterusnya.
Yang sebenarnya akan mendapatkan anda nod bahawa mata kursor untuk. Bahawa nilai seterusnya.
Jadi bukannya mempunyai bintang dan titik, anda menggantikan bahawa dengan anak panah.
Berhati-hati untuk memastikan bahawa anda cuba untuk menggunakan sintaks ini.
>> Sekarang kita mempunyai kursor kita, jika kita mahu untuk mengakses nilai,
sebelum ini, kita terpaksa kursor-> seterusnya,
tetapi untuk mengakses nilai pada nod bahawa kursor menunjuk ke, kita hanya sekadar mengatakan
nod-> nilai.
Dari situ, ia adalah jenis data apa yang kita telah ditakrifkan nilai-nilai dan nodus menjadi.
Jika ia nod int, maka kursor-> nilai hanya akan menjadi integer.
Jadi, kita boleh melakukan operasi pada itu, periksa equalities, menyerahhakkan nilai-nilai yang berbeza, dan lain-lain
Jadi maka apa yang anda mahu lakukan jika anda mahu menggerakkan kursor anda kepada orang yang seterusnya,
anda sebenarnya menukar nilai kursor.
Sejak kursor penunjuk nod, anda menukar alamat penunjuk sebenar
alamat nod seterusnya dalam senarai anda.
Ini adalah hanya beberapa kod di mana anda boleh melelar.
Di mana saya mempunyai komen melakukan sesuatu,
itulah di mana anda mungkin akan mengakses nilai
atau melakukan sesuatu untuk dilakukan dengan nod yang tertentu.
Untuk memulakan ia dimatikan, saya mengatakan bahawa kursor saya pada mulanya
akan untuk menunjukkan elemen yang pertama dalam senarai berkaitan.
Dan sebagainya sehingga ke hadapan, saya ditakrifkan sebagai ketua nod.
>> Seperti yang saya nyatakan sebelum ini, membebaskan adalah benar-benar penting.
Anda ingin memastikan bahawa anda membebaskan setiap elemen dalam senarai sebaik sahaja anda selesai dengan ia.
Apabila anda tidak perlu untuk rujukan mana-mana mereka petunjuk lagi,
anda ingin memastikan bahawa anda membebaskan semua mereka petunjuk.
Tetapi anda ingin menjadi sangat berhati-hati di sini kerana anda mahu mengelakkan sebarang kebocoran memori.
Jika anda bebas seseorang pramatang, maka semua petunjuk bahawa titik nod
akan hilang.
Melangkah kembali ke contoh orang yang membuat ia sedikit kepentingan lebih tinggi,
mari kita mempunyai orang-orang ini, kecuali dalam kes ini mereka berlegar di atas tasik dengan raksasa.
Kami mahu memastikan bahawa apabila kita bebas, kita tidak kehilangan
dan membiarkan pergi mana-mana nod sebelum kita telah benar-benar dibebaskan mereka.
Sebagai contoh, jika anda adalah untuk hanya memanggil percuma pada lelaki ini di sini,
maka dia akan dibebaskan, tetapi kemudian semua ini lelaki maka akan hilang
dan mereka akan hanyut dan jatuh.
Jadi, kita mahu pastikan bahawa sebaliknya, kita mahu mengekalkan pautan ke seluruh.
Penunjuk kepala kita, yang mata kepada unsur yang pertama dalam senarai.
Ia adalah jenis seperti tali sauh orang pertama.
Apa yang anda mungkin mahu lakukan apabila anda membebaskan senarai -
Jika anda ingin membebaskan elemen pertama yang pertama, maka anda boleh mempunyai penunjuk sementara
bahawa mata kepada apa jua elemen pertama.
Jadi anda mempunyai penunjuk sementara anda menunjuk sini.
Dengan cara itu, kita perlu memegang nod pertama.
Dan kemudian, kerana kita tahu bahawa nod pertama akan dibebaskan,
maka kita boleh bergerak ini tali, sauh ini, kepala kita,
untuk benar-benar menunjukkan apa yang pertama menunjuk ke.
Jadi kepala ini sebenarnya menunjukkan kepada elemen kedua sekarang.
Sekarang kita dibenarkan untuk membebaskan apa yang disimpan dalam menggoda,
dan sebagainya kita boleh memadam bahawa tanpa ia membahayakan semua nod lain dalam senarai kami.
Satu lagi cara yang anda boleh lakukan ini boleh menjadi
setiap kali anda hanya membebaskan elemen terakhir dalam senarai
kerana mereka dijamin tidak akan menunjukkan apa-apa.
Jadi, anda hanya boleh membebaskan satu ini, maka yang satu ini, maka percuma satu ini.
Yang pasti kerja-kerja tetapi adalah agak perlahan kerana oleh sifat senarai yang dikaitkan,
kita tidak boleh hanya segera melompat kepada yang terakhir.
Kita perlu merentasi setiap elemen dalam senarai berkaitan
dan memeriksa sama ada salah satu yang menunjuk ke NULL, memeriksa setiap masa,
dan kemudian apabila kita sampai akhir, maka percuma yang.
Jika anda untuk melakukan proses ini, anda sebenarnya akan memeriksa di sini,
memeriksa di sini, kemudian memeriksa di sini, membebaskan,
kemudian akan kembali, memeriksa sini, memeriksa sini, membebaskan,
memeriksa di sini, dan kemudian membebaskan ia.
Yang mengambil masa sedikit lebih. Yeah.
>> [Pelajar] Adakah ia mungkin untuk membuat senarai yang dikaitkan yang menyimpan penunjuk keluar ke akhir?
Yang pasti akan berlaku.
Untuk mengulangi soalan, ia mungkin untuk mempunyai senarai struktur yang dikaitkan
seperti yang anda mempunyai penunjuk yang menunjuk ke akhir senarai dikaitkan?
Saya mengatakan bahawa mungkin, dan setiap kali anda memasukkan sesuatu ke dalam senarai dikaitkan anda
anda akan mempunyai untuk mengemaskinikan bahawa penunjuk dan perkara-perkara seperti itu.
Anda akan mempunyai ekor * nod, misalnya.
Tetapi apabila anda melaksanakan ciri ini, anda perlu berfikir off perdagangan,
suka berapa kali saya akan iterating lebih ini,
bagaimana sukar ia akan menjadi menjejaki ekor serta kepala
serta iterator saya, dan hal-hal seperti itu.
Adakah itu? >> [Pelajar] Yeah.
Ia mungkin, tetapi dari segi keputusan reka bentuk, anda perlu menimbang pilihan.
>> Berikut adalah rangka kod yang akan membolehkan anda untuk membebaskan setiap elemen dalam senarai berkaitan.
Sekali lagi, kerana saya iterating atas senarai berkaitan, saya akan mahu mempunyai beberapa jenis kursor
atau iterator.
Kami iterating sehingga kursor NULL.
Anda tidak mahu untuk melelar apabila kursor anda adalah NULL
kerana itu bermakna bahawa tidak ada apa-apa dalam senarai.
Jadi maka di sini saya membuat * nod sementara
menunjuk kepada apa yang saya mempertimbangkan pertama senarai saya,
dan kemudian saya menggerakkan kursor saya menjelang 1 dan kemudiannya bebas apa yang saya ada dalam simpanan sementara.
>> Sekarang kita datang untuk memasukkan ke dalam senarai berkaitan.
Saya mempunyai tiga nod dalam senarai berpaut saya, dan mari kita pergi dengan kes mudah
di mana kita mahu memasukkan nod yang lain pada akhir senarai dikaitkan kami.
Untuk berbuat demikian, kita akan lakukan ialah kita akan merentasi
untuk mencari di mana akhir semasa senarai berkaitan, jadi mana-mana nod menunjuk ke Nol -
yang satu ini -
dan kemudian berkata, sebenarnya, yang satu ini tidak akan menjadi nod terakhir;
kita sebenarnya akan mempunyai satu sama lain.
Jadi, kita akan mempunyai ini semasa satu titik untuk apa sahaja yang kita memasukkan.
Jadi sekarang ini orang merah di sini menjadi nod terakhir dalam senarai berkaitan.
Dan sebagainya ciri nod terakhir dalam senarai berkaitan adalah bahawa ia menjurus kepada NULL.
Demikian maka apa yang kita perlu lakukan ialah menetapkan penunjuk lelaki ini merah untuk null. Di sana.
>> Tetapi bagaimana jika kita mahu memasukkan nod di antara satu kedua dan ketiga?
Bahawa seseorang itu tidak cukup sebagai mudah kerana kita mahu memastikan
bahawa kita tidak melepaskan mana-mana nod dalam senarai dikaitkan kami.
Apa yang kita perlu lakukan adalah pastikan bahawa kita menambat diri kita untuk setiap satu.
Sebagai contoh, mari kita memanggil ini yang kedua.
Jika anda berkata yang kedua sekarang menunjukkan kepada yang satu ini baru
dan anda hanya dibuat penunjuk sana, kemudian yang akan mengakibatkan lelaki ini hilang
kerana tidak ada mana-mana pautan kepadanya.
Sebaliknya - Saya akan menarik ini lagi. Maafkan kebolehan artistik saya.
Kita tahu bahawa kita tidak boleh hanya terus menghubungkan 2 yang baru.
Kita perlu pastikan bahawa kita berpegang kepada yang terakhir.
Apa yang kita mungkin mahu lakukan adalah mempunyai penunjuk sementara
kepada elemen yang akan dilampirkan.
Jadi maka kita mempunyai penunjuk sementara di sana.
Sejak kita tahu bahawa ini satu ketiga sedang disimpan mengesan,
2 kini boleh menghubungkan kepada satu baru kami.
Dan jika ini lelaki merah baru akan menjadi di antara 2 dan 3,
maka apa yang penunjuk bahawa lelaki akan untuk menunjukkan? >> [Pelajar] Temp.
Suhu. Yeah.
Jadi maka nilai seterusnya ini lelaki merah akan menjadi temp.
Apabila anda memasukkan ke dalam senarai yang berkaitan, kita melihat bahawa kita boleh
mudah menambah sesuatu ke akhir dengan mewujudkan pelbagai sementara,
atau jika kita mahu menambah sesuatu ke tengah-tengah pelbagai kami,
maka ia akan mengambil sedikit lebih shuffling sekitar.
Jika anda mahu, misalnya, mempunyai senarai berpaut disusun,
maka anda perlu jenis berat kos dan faedah itu
kerana jika anda mahu mempunyai pelbagai disusun, ini bermakna bahawa setiap kali yang anda masukkan ke dalam,
ia akan mengambil masa sedikit lebih.
Walau bagaimanapun, jika anda mahu kemudian, seperti yang kita akan dapati kita akan mahu,
carian melalui senarai berkaitan, maka ia mungkin lebih mudah jika anda tahu bahawa segala-galanya teratur.
Jadi anda mungkin mahu untuk menimbang kos dan faedah itu.
>> Satu lagi cara untuk memasukkan ke dalam senarai berkaitan adalah untuk memasukkan ke awal sangat senarai.
Jika kita menarik sauh kami di sini - ini adalah kepala kita -
dan kemudian telah orang-orang ini dikaitkan dengan,
dan kemudian kita mempunyai nod baru akan dimasukkan ke dalam permulaan,
maka apa yang kita mungkin mahu lakukan?
Apa yang akan menjadi salah dengan hanya mengatakan saya mahu untuk menghubungkan merah kepada biru,
kerana itulah yang pertama?
Apa yang akan berlaku di sini?
Semua ketiga-tiga akan tersesat.
Jadi kita tidak mahu berbuat demikian.
Sekali lagi, kita telah belajar bahawa kita perlu mempunyai beberapa jenis penunjuk sementara.
Mari kita memilih untuk mempunyai satu titik sementara kepada lelaki ini.
Kemudian kita boleh mempunyai satu titik biru untuk sementara
dan kemudian titik merah kepada biru.
Sebab mengapa saya menggunakan orang di sini adalah kerana kita benar-benar mahu untuk menggambarkan
berpegang kepada rakyat dan memastikan bahawa kita mempunyai pautan kepada mereka
sebelum kita melepaskan tangan lain atau sesuatu seperti itu.
>> Sekarang kita mempunyai rasa senarai yang dipautkan - bagaimana kita boleh mewujudkan senarai berpaut
dan mewujudkan struktur bagi yang terdiri daripada definisi jenis untuk nod
dan kemudian memastikan bahawa kita mempunyai penunjuk kepada kepala senarai yang dikaitkan -
sekali kita perlu dan kita tahu bagaimana untuk merentasi melalui array,
mengakses pelbagai elemen, kita tahu bagaimana untuk memasukkan dan kita tahu bagaimana untuk membebaskan mereka,
maka kita boleh masuk ke dalam ejaan.
Seperti biasa, kita mempunyai seksyen soalan-soalan yang akan mendapatkan anda digunakan untuk operasi dengan senarai berkaitan
dan struktur yang berbeza seperti barisan dan susunan.
Kemudian kita boleh bergerak ke dalam ejaan.
>> Ejaan mempunyai kod pengagihan beberapa fail penting.
Mula-mula kita dapati bahawa kita mempunyai Makefile ini di sini,
yang kita tidak benar-benar yang dihadapi sebelum ini.
Jika anda melihat di dalam folder pset5, anda akan melihat bahawa anda mempunyai fail h,
maka anda mempunyai dua c fail.
Apa Makefile ini tidak sebelum ini, kita hanya akan menaip membuat dan maka nama program
dan kemudian kita akan melihat semua ini hujah dan bendera lulus ke pengkompil.
Apa Makefile tidak membolehkan kita untuk menyusun beberapa fail sekaligus
dan lulus dalam bendera yang kita mahu.
Di sini kita hanya melihat ada fail pengepala di sini.
Kemudian kita sebenarnya mempunyai dua fail sumber.
Kami mempunyai speller.c dan dictionary.c.
Anda dialu-alukan untuk mengedit Makefile jika anda mahu.
Perhatikan bahawa di sini jika anda menaip bersih, maka apa yang ia adalah sebenarnya membuang apa-apa
yang adalah teras.
Jika anda mendapat suatu kesalahan segmentasi, pada dasarnya anda mendapat tempat pembuangan teras.
Jadi fail ini sedikit hodoh akan muncul dalam direktori yang dipanggil teras anda.
Anda akan mahu untuk menghapuskan bahawa untuk membuat ia bersih.
Ia membuang mana-mana fail exe dan fail o.
>> Mari kita lihat ke dalam dictionary.h.
Ini mengatakan bahawa ia mengisytiharkan fungsi kamus.
Kami mempunyai panjang maksimum bagi mana-mana perkataan di dalam kamus.
Kami mengatakan bahawa ini akan menjadi perkataan yang mungkin terpanjang. Ia adalah sebanyak 45 panjang.
Jadi kita tidak akan mempunyai apa-apa perkataan yang melebihi panjang yang.
Di sini kita hanya mempunyai prototaip fungsi.
Kami tidak mempunyai pelaksanaan sebenar kerana itulah apa yang kita akan lakukan untuk pset ini.
Tetapi apa yang ini tidak adalah kerana kita sedang berurusan dengan fail yang lebih besar di sini
dan fungsi pada skala yang lebih besar, ia berguna untuk mempunyai fail h
supaya orang lain membaca atau menggunakan kod anda boleh memahami apa yang berlaku.
Dan mungkin mereka mahu untuk melaksanakan cuba jika anda lakukan jadual hash atau sebaliknya.
Kemudian mereka akan mengatakan fungsi beban saya,
pelaksanaan sebenar akan berbeza, tetapi prototaip ini tidak akan berubah.
Di sini kita telah memeriksa, yang mengembalikan benar jika perkataan yang diberikan di dalam kamus.
Kemudian kita mempunyai beban, yang pada dasarnya mengambil dalam fail kamus
dan kemudian memuatkan ke dalam beberapa struktur data.
Kami mempunyai saiz, yang, apabila dipanggil, mengembalikan saiz kamus anda,
berapa banyak kata-kata yang disimpan di dalamnya,
dan kemudian memunggah, yang membebaskan memori semua yang anda mungkin telah diambil
semasa membuat kamus anda.
>> Mari kita lihat pada dictionary.c.
Kita lihat bahawa ia kelihatan sangat serupa ke dictionary.h, kecuali kini ia hanya mempunyai semua ini Todos di dalamnya.
Dan supaya kerja anda. Akhirnya, anda akan mengisi speller.c dengan semua kod ini.
Dictionary.c, apabila berjalan, tidak benar-benar akan melakukan apa-apa,
jadi kita melihat ke arah speller.c untuk melihat pelaksanaan sebenar pemeriksa ejaan.
Walaupun anda tidak akan menyunting mana-mana kod ini,
ia adalah penting untuk membaca, memahami apabila beban dipanggil, apabila saya memanggil cek,
hanya untuk memahami, memetakan ia keluar, melihat bagaimana fungsi berfungsi.
Kita lihat bahawa ia memeriksa penggunaan yang betul.
Pada asasnya, apabila seseorang berjalan pengeja, ini menunjukkan bahawa ia adalah pilihan
bagi mereka untuk lulus dalam fail kamus kerana ada akan menjadi fail lalai kamus.
Dan kemudian mereka perlu lulus dalam teks untuk menjadi eja.
tawaran rusage dengan masa kerana sebahagian pset ini yang kita akan berurusan dengan kemudian
bukan sahaja mendapat berfungsi ejaan pemeriksa bekerja
tetapi sebenarnya mendapat ia menjadi cepat.
Dan demikian maka yang mana rusage akan datang masuk
Di sini, kita lihat panggilan pertama salah fail dictionary.c kami, yang merupakan beban.
Beban mengembalikan benar atau palsu - benar apabila kejayaan, palsu atas kegagalan.
Jadi jika kamus tidak dimuatkan dengan betul, maka speller.c itu akan kembali 1 dan berhenti.
Tetapi jika ia tidak beban yang betul, maka ia akan terus.
Kami terus, dan kita lihat beberapa fail I / O di sini,
di mana ia akan berurusan dengan membuka fail teks.
Di sini, apa ini tidak adalah ejaan memeriksa setiap perkataan tunggal dalam teks.
Jadi apa speller.c melakukan di sini iterating setiap perkataan dalam fail teks
dan kemudian memeriksa mereka di dalam kamus.
Di sini, kita mempunyai Boolean silap eja yang akan melihat jika cek mengembalikan benar atau tidak.
Jika perkataan itu sebenarnya adalah di dalam kamus, maka cek akan kembali benar.
Ini bermakna bahawa perkataan itu tidak silap eja.
Jadi silap eja akan menjadi palsu, dan itulah sebabnya kami mempunyai letupan di sana, petunjuk.
Kami terus pergi, dan kemudian ia menjejaki berapa banyak kata yang salah Mengeja
terdapat dalam fail.
Ia terus dan menutup fail.
Maka di sini, ia melaporkan berapa banyak kata yang salah Mengeja anda mempunyai.
Ia mengira berapa banyak masa ia mengambil masa untuk memuatkan kamus,
berapa banyak masa ia mengambil masa untuk memeriksa,
berapa banyak masa ia mengambil masa untuk mengira saiz,
yang, seperti yang kita akan pergi, harus sangat kecil,
dan kemudian berapa banyak masa ia mengambil masa untuk memunggah kamus.
Di sini sehingga di atas kita lihat panggilan untuk memunggah di sini.
Jika kita memeriksa saiz di sini,
maka kita melihat bahawa di sini adalah panggilan untuk saiz di mana ia menentukan saiz kamus.
Menggerunkan.
>> Tugas kita untuk pset ini adalah untuk melaksanakan beban, yang akan memuatkan kamus
struktur data - yang mana anda memilih, sama ada jadual hash atau cuba -
dengan perkataan dari fail kamus.
Kemudian anda mempunyai saiz, yang akan mengembalikan bilangan perkataan dalam kamus.
Dan jika anda melaksanakan beban dalam cara yang bijak, maka saiz harus agak mudah.
Maka anda telah mendaftar, yang akan memeriksa jika satu perkataan yang diberikan di dalam kamus.
Jadi speller.c pas dalam rentetan, dan kemudian anda perlu untuk memeriksa sama ada rentetan itu
yang terkandung dalam kamus anda.
Notis bahawa kita umumnya mempunyai kamus standard,
tetapi dalam pset ini, pada dasarnya mana-mana kamus diluluskan di dalam mana-mana bahasa.
Jadi kita tidak boleh hanya menganggap bahawa perkataan THE berada di dalam.
Foobar perkataan boleh ditakrifkan dalam kamus tertentu yang kita lulus.
Dan maka kita telah memunggah, yang membebaskan kamus dari ingatan.
>> Pertama, saya ingin untuk pergi ke atas kaedah jadual hash
tentang bagaimana kita boleh melaksanakan semua daripada mereka empat fungsi,
dan kemudian saya akan pergi lebih cuba kaedah, bagaimana kita melaksanakan mereka empat fungsi,
dan pada akhir bercakap mengenai beberapa tip umum apabila anda membuat pset yang
dan juga bagaimana anda mungkin boleh menggunakan Valgrind untuk memeriksa kebocoran memori.
>> Mari kita masuk ke dalam kaedah jadual hash.
Satu jadual hash terdiri daripada senarai baldi.
Setiap nilai, setiap perkataan, akan pergi ke dalam salah satu daripada baldi ini.
Satu jadual hash ideal sama rata mengedarkan semua nilai-nilai yang anda lulus dalam
dan kemudian populates mereka dalam baldi itu bahawa setiap baldi
mempunyai kira-kira nombor yang sama nilai di dalamnya.
Struktur untuk jadual hash, kita mempunyai pelbagai senarai yang dipautkan.
Apa yang kita lakukan adalah apabila kita lulus dalam nilai, kita memeriksa mana nilai yang perlu dimiliki,
baldi yang ia milik, dan kemudian meletakkannya ke dalam senarai berkaitan dikaitkan dengan baldi itu.
Di sini, apa yang saya ada adalah fungsi hash.
Ia adalah jadual hash int.
Jadi untuk baldi pertama, sebarang integer bawah 10 pergi ke dalam baldi yang pertama.
Mana-mana integer melebihi 10 tetapi di bawah 20 pergi ke kedua,
dan kemudian sebagainya dan sebagainya.
Bagi saya, baldi setiap mewakili nombor-nombor ini.
Walau bagaimanapun, katakan saya adalah untuk lulus dalam 50, misalnya.
Nampaknya seolah-olah tiga pertama mengandungi pelbagai sepuluh nombor.
Tetapi saya mahu membenarkan jadual hash saya untuk mengambil apa-apa jenis integer,
begitu maka saya akan perlu untuk menapis semua nombor di atas 30 ke dalam baldi lalu.
Dan demikian maka yang akan menyebabkan sejenis jadual hash tidak seimbang.
Mengulangi, jadual hash hanya pelbagai baldi
di mana setiap baldi adalah senarai yang berkaitan.
Dan sebagainya untuk menentukan di mana nilai setiap pergi, yang baldi ia masuk ke dalam,
anda akan mahu apa yang dipanggil fungsi hash
yang mengambil nilai dan kemudian mengatakan nilai ini sepadan dengan baldi tertentu.
Jadi sehingga di atas dalam contoh ini, fungsi hash saya mengambil setiap nilai.
Ia diperiksa sama ada ia adalah kurang daripada 10.
Jika ia adalah, ia akan meletakkan ia ke dalam baldi yang pertama.
Ia memeriksa sama ada ia adalah kurang daripada 20, meletakkan ia ke dalam kedua jika benar,
cek jika ia adalah kurang daripada 30, dan kemudian meletakkan ia ke dalam baldi ketiga,
dan kemudian segala-galanya hanya jatuh ke baldi keempat.
Jadi apabila anda mempunyai nilai, fungsi hash anda
akan meletakkan nilai itu ke dalam baldi sesuai.
Fungsi hash pada dasarnya perlu tahu berapa banyak baldi anda mempunyai.
Jadual hash saiz anda, bilangan baldi anda mempunyai,
yang akan menjadi nombor tetap yang terpulang kepada anda, bagi anda untuk membuat keputusan,
tetapi ia akan menjadi nombor tetap.
Jadi fungsi hash anda akan bergantung kepada bahawa untuk menentukan baldi kunci yang masuk ke dalam setiap
itu bahawa ia sama rata.
Serupa dengan pelaksanaan senarai yang dipautkan kami, kini setiap nod dalam jadual hash
sebenarnya akan mempunyai char jenis.
Jadi kita mempunyai pelbagai char dipanggil perkataan dan kemudian satu lagi penunjuk kepada nod seterusnya,
yang masuk akal kerana ia akan menjadi senarai yang dipautkan.
Ingat apabila kita telah dikaitkan senarai, saya membuat kepala * nod yang dipanggil
yang menunjuk kepada nod pertama dalam senarai berkaitan.
Tetapi bagi jadual hash kita, kerana kita mempunyai pelbagai dikaitkan senarai,
apa yang kita mahu ialah kita mahu jadual hash kami untuk menjadi seperti, "Apakah baldi?"
Baldi adalah hanya senarai penunjuk nod,
dan sebagainya setiap unsur dalam baldi sebenarnya menunjuk kepada senarai yang sama berkaitan.
Untuk kembali ke skematik ini, anda akan melihat bahawa baldi sendiri adalah anak panah,
tidak nod sebenar.
Salah satu harta penting fungsi hash adalah bahawa mereka berada berketentuan.
Ini bermakna bahawa apabila anda hash nombor 2,
ia perlu sentiasa kembali baldi yang sama.
Setiap nilai tunggal yang masuk ke dalam fungsi hash, jika berulang,
untuk mendapatkan indeks yang sama.
Jadi fungsi hash anda mengembalikan indeks array
di mana nilai yang dimiliki.
Seperti yang saya nyatakan sebelum ini, bilangan baldi ditetapkan,
dan sebagainya telunjuk anda bahawa anda kembali mempunyai kurang daripada bilangan baldi
tetapi lebih besar daripada 0.
Sebab mengapa kita mempunyai fungsi hash dan bukannya hanya satu senarai tunggal dikaitkan
atau satu array tunggal adalah bahawa kita mahu menjadi dapat untuk melompat ke bahagian tertentu yang paling mudah
jika kita tahu ciri-ciri nilai -
bukannya terpaksa mencari melalui kamus keseluruhan keseluruhan,
dapat untuk melompat ke seksyen tertentu.
Fungsi hash anda harus mengambil kira bahawa ideal,
baldi masing-masing mempunyai kira-kira jumlah yang sama kunci.
Sejak jadual hash adalah satu siri senarai yang dipautkan,
maka senarai yang dikaitkan sendiri akan mempunyai lebih daripada satu nod.
Dalam contoh sebelum ini, dua nombor yang berbeza, walaupun mereka tidak sama,
apabila dicincang, akan mengembalikan indeks yang sama.
Jadi, apabila anda berurusan dengan kata-kata, satu perkataan apabila dicincang
akan menjadi nilai yang sama hash sebagai perkataan lain.
Itulah apa yang kita panggil perlanggaran, apabila kita mempunyai nod bahawa, apabila dicincang,
senarai dikaitkan di baldi yang tidak kosong.
Teknik yang kita panggil di sana adalah linear menyelesaikan sesuatu,
di mana anda pergi ke senarai berkaitan dan kemudian mencari di mana anda mahu untuk memasukkan bahawa nod
kerana anda mempunyai perlanggaran.
Anda boleh lihat bahawa mungkin ada trade-off di sini, betul-betul?
Jika anda mempunyai jadual hash yang sangat kecil, jumlah yang sangat kecil baldi,
maka anda akan mempunyai banyak perlanggaran.
Tetapi kemudian jika anda membuat jadual hash yang sangat besar,
anda mungkin akan mengurangkan perlanggaran,
tetapi ia akan menjadi struktur data yang sangat besar.
Ada akan menjadi keseimbangan dengan itu.
Jadi, apabila anda membuat pset anda, cuba untuk bermain-main
antara mungkin membuat jadual hash yang lebih kecil
tetapi kemudian mengetahui bahawa ia akan mengambil masa yang lama untuk merentasi elemen-elemen yang berbeza
mereka senarai yang dipautkan.
>> Apa beban akan lakukan adalah melelar lebih setiap perkataan dalam kamus.
Ia pas penunjuk kepada fail kamus.
Jadi, anda akan mengambil kesempatan fail I / O fungsi yang anda menguasai dalam pset4
dan melelar lebih setiap perkataan dalam kamus.
Anda mahu setiap perkataan dalam kamus untuk menjadi nod baru,
dan anda akan meletakkan setiap satu daripada nod-nod di dalam struktur data kamus anda.
Apabila anda mendapat satu perkataan baru, anda tahu bahawa ia akan menjadi nod.
Jadi, anda boleh pergi merta dan malloc penunjuk nod bagi setiap perkataan baru yang anda mempunyai.
Di sini saya memanggil penunjuk nod new_node saya dan saya mallocing apa? Saiz nod.
Kemudian membaca rentetan sebenar dari fail, kerana kamus sebenarnya disimpan
oleh perkataan dan kemudian barisan baru, apa yang kita boleh mengambil kesempatan daripada
adalah fscanf fungsi,
mana fail fail kamus bahawa kita lulus,
jadi ia mengimbas fail untuk rentetan dan tempat-tempat yang tali ke dalam hujah terakhir.
Jika anda ingat kembali kepada salah satu kuliah, apabila kita pergi ke
dan jenis dikupas lapisan kembali di perpustakaan CS50,
kita menyaksikan pelaksanaan fscanf sana.
Untuk kembali ke fscanf, kita mempunyai fail yang kita sedang membaca dari,
kita sedang mencari string dalam fail itu, dan kemudian kita meletakkan ia ke dalam
di sini saya mempunyai new_node-> perkataan kerana new_node adalah penunjuk nod,
bukan nod sebenar.
Jadi maka saya cakapkan new_node, saya mahu pergi ke nod yang ia menunjuk ke
dan kemudian memberikan nilai itu kepada perkataan.
Kami mahu kemudian mengambil perkataan itu dan memasukkannya ke dalam jadual hash.
Sedar bahawa kita dibuat new_node penunjuk nod
kerana kita akan mahu tahu apa alamat nod tersebut adalah
apabila kita memasukkan ia masuk kerana struktur nod sendiri, struct itu,
adalah bahawa mereka mempunyai penunjuk kepada nod baru.
Jadi maka apa alamat nod yang pergi untuk menunjukkan?
Alamat akan menjadi new_node.
Adakah yang masuk akal, mengapa kita membuat new_node * nod sebagai bertentangan dengan nod?
Okay.
Kami mempunyai perkataan. Itu nilai new_node-> perkataan.
Yang mengandungi perkataan daripada kamus yang kita mahu untuk input.
Jadi apa yang kita mahu lakukan ialah kita mahu untuk memanggil fungsi hash kami pada tali itu
kerana fungsi hash kita mengambil dalam rentetan dan kemudian kembali kita integer,
mana integer bahawa indeks mana hashtable pada indeks yang mewakili baldi yang.
Kami mahu mengambil indeks itu dan kemudian pergi kepada indeks yang jadual hash
dan kemudian gunakan bahawa senarai yang dipautkan untuk memasukkan nod pada new_node.
Ingatlah bahawa bagaimanapun anda memutuskan untuk memasukkan nod anda,
sama ada ia adalah di tengah-tengah jika anda mahu untuk menyusun
atau pada awal atau di akhir, pastikan bahawa nod terakhir anda sentiasa mata kepada NULL
kerana itulah satu-satunya cara yang kita tahu di mana elemen terakhir senarai dikaitkan kami.
>> Jika saiz adalah integer yang mewakili bilangan perkataan dalam kamus,
maka salah satu cara untuk melakukan ini adalah bahawa apabila saiz dipanggil
kita pergi melalui setiap elemen dalam jadual hash kami
dan kemudian melelar melalui senarai setiap dikaitkan dalam jadual hash
dan kemudian mengira panjang itu, meningkat 1 kaunter kami dengan 1.
Tetapi setiap kali bahawa saiz dipanggil, yang akan mengambil masa yang lama
kerana kita akan menjadi linear menyelesaikan sesuatu setiap senarai tunggal yang berkaitan.
Sebaliknya, ia akan menjadi lebih mudah jika anda menjejaki berapa banyak kata-kata yang diluluskan.
Jadi, maka jika anda termasuk kaunter dalam fungsi beban anda
update seperti yang diperlukan, maka kaunter, jika anda menetapkan pembolehubah global,
akan dapat diakses oleh saiz.
Jadi apa saiz hanya boleh lakukan dalam satu baris, hanya memulangkan nilai kaunter,
saiz kamus yang anda sudah diuruskan dengan beban.
Itulah apa yang saya maksudkan apabila saya berkata jika anda melaksanakan beban dalam cara membantu,
maka saiz akan menjadi agak mudah.
>> Jadi sekarang kita mendapatkan untuk memeriksa.
Sekarang kita sedang berurusan dengan perkataan dari fail input teks,
dan sebagainya kita akan memeriksa sama ada semua kata-kata input
sebenarnya dalam kamus atau tidak.
Similar Kacau, kita mahu untuk membolehkan tidak sensitif huruf.
Anda ingin memastikan bahawa semua perkataan lulus dalam, walaupun mereka berada kes bercampur,
apabila dipanggil dengan Bandingkan tali, adalah bersamaan.
Perkataan dalam fail teks kamus sebenarnya semua huruf kecil.
Satu lagi perkara adalah bahawa anda boleh mengandaikan bahawa setiap perkataan meninggal dalam setiap, tali,
akan sama ada abjad atau mengandungi koma.
Apostrofi akan menjadi perkataan yang sah di dalam kamus kami.
Jadi jika anda mempunyai satu perkataan dengan apostrofi S, itulah perkataan sebenar yang sah dalam kamus anda
yang akan menjadi salah satu daripada nod dalam jadual hash anda.
Semak beroperasi dengan jika perkataan itu wujud, maka ia mendapat menjadi dalam jadual hash kami.
Sekiranya perkataan ada di dalam kamus, maka semua perkataan di dalam kamus dalam jadual hash,
jadi mari kita lihat perkataan ini dalam jadual hash.
Kita tahu bahawa sejak kita melaksanakan fungsi hash kami
seperti bahawa setiap perkataan yang unik sentiasa dicincang kepada nilai yang sama,
maka kita tahu bahawa bukannya mencari melalui jadual hash keseluruhan keseluruhan kami,
kita sebenarnya boleh mencari senarai berpaut bahawa perkataan itu seharusnya tergolong.
Jika ia berada di dalam kamus, maka ia akan menjadi dalam baldi itu.
Apa yang boleh kita lakukan, jika perkataan adalah nama rentetan diluluskan pada kami,
kita hanya boleh hash bahawa perkataan dan melihat senarai berkaitan
pada nilai hashtable [hash (perkataan)].
Dari situ, apa yang boleh kita lakukan ialah kita mempunyai subset yang lebih kecil nod untuk mencari perkataan ini,
dan supaya kita boleh merentasi senarai berpaut, dengan menggunakan contoh dari awal Walkthrough,
dan kemudian memanggil rentetan bandingkan apabila perkataan mana-mana kursor menunjuk ke,
bahawa perkataan, dan lihat sama ada mereka istimewa.
Bergantung kepada cara yang anda mengatur fungsi hash anda,
jika ia disusun, anda mungkin tidak dapat untuk kembali palsu sedikit lebih awal,
tetapi jika ia Unsorted, maka anda mahu terus menyeberangi melalui senarai dikaitkan anda
sehingga anda menjumpai elemen terakhir senarai.
Dan jika anda masih tidak dijumpai perkataan oleh masa yang anda telah sampai ke penghujung senarai berkaitan,
yang bermaksud bahawa perkataan anda tidak wujud di dalam kamus,
dan sebagainya perkataan itu adalah tidak sah,
dan cek perlu kembali palsu.
>> Sekarang kita sampai kepada memunggah, di mana kita mahu untuk membebaskan semua nod yang kita telah malloc'd,
begitu bebas semua nod dalam jadual hash kami.
Kami akan mahu untuk melelar semua senarai dikaitkan dan bebas semua nod dalam itu.
Jika anda melihat ke atas dalam Walkthrough contoh di mana kita membebaskan senarai berpaut,
maka anda akan mahu mengulangi proses itu bagi setiap elemen dalam jadual hash.
Dan saya akan pergi ke ini ke arah akhir Walkthrough,
tetapi Valgrind adalah alat yang mana anda boleh melihat jika anda telah dibebaskan
setiap nod yang anda telah malloc'd atau apa-apa lain yang anda telah malloc'd, apa-apa penunjuk lain.
Jadi itulah jadual hash, di mana kita mempunyai nombor terhingga baldi
dan fungsi hash yang akan mengambil nilai dan kemudian menetapkan nilai yang baldi tertentu.
>> Sekarang kita datang kepada cuba.
Cuba jenis kelihatan seperti ini, dan saya juga akan menarik keluar contoh.
Pada asasnya, anda mempunyai pelbagai keseluruhan surat yang berpotensi,
dan kemudian apabila anda membina perkataan,
surat yang boleh dikaitkan untuk kamus kepada pelbagai kemungkinan.
Sesetengah perkataan bermula dengan C tetapi kemudian terus dengan A,
tetapi yang lain terus dengan O, sebagai contoh.
Indone adalah cara yang menggambarkan semua kemungkinan kombinasi kata-kata.
Indone A akan menjejaki urutan huruf yang terdiri daripada perkataan,
Sisihan apabila perlu, apabila satu huruf boleh diikuti oleh pelbagai surat,
dan pada akhir menunjukkan pada setiap titik sama ada perkataan itu adalah sah atau tidak
kerana jika anda sedang ejaan MAT perkataan, MA Saya tidak fikir adalah perkataan yang sah, tetapi MAT adalah.
Dan supaya di indone anda, ia akan menunjukkan bahawa selepas MAT itulah sebenarnya satu perkataan yang sah.
Setiap nod dalam indone kita sebenarnya akan mengandungi pelbagai petunjuk nod,
dan kita akan mempunyai, khususnya, 27 orang penunjuk nod,
salah bagi setiap huruf dalam abjad serta watak apostrofe.
Setiap elemen dalam array bahawa dirinya akan menuding kepada nod yang lain.
Jadi, jika nod tersebut adalah NULL, jika tiada apa-apa selepas itu,
maka kita tahu bahawa tidak ada surat lagi dalam urutan perkataan itu.
Tetapi jika nod tersebut tidak NULL, ini bermakna bahawa terdapat lebih huruf dalam urutan surat itu.
Dan kemudian tambahan pula, setiap nod menunjukkan sama ada ia adalah aksara terakhir perkataan atau tidak.
>> Mari pergi ke contoh indone satu.
Pertama Saya mempunyai bilik untuk 27 nod dalam pelbagai ini.
Jika saya mempunyai BAR perkataan -
Jika saya mempunyai BAR perkataan dan saya mahu untuk memasukkan bahawa dalam,
huruf pertama ialah B, jadi jika indone saya adalah kosong,
B adalah huruf kedua abjad, jadi saya akan memilih untuk meletakkan ini di sini pada indeks ini.
Saya akan mempunyai B di sini.
B akan menjadi nod yang mata kepada pelbagai lain semua watak-watak yang mungkin
yang boleh mengikuti selepas huruf B.
Dalam kes ini, saya berurusan dengan BAR perkataan, jadi A akan pergi di sini.
Selepas A, saya mempunyai huruf R, maka A mata sekarang gabungan sendiri,
dan kemudian R akan berada di sini.
BAR adalah satu perkataan yang lengkap, demikian maka saya akan mempunyai titik R ke nod yang lain
yang mengatakan bahawa perkataan itu adalah sah.
Nod juga akan mempunyai pelbagai nod,
tetapi mereka mungkin NULL.
Tetapi pada dasarnya, ia boleh terus seperti itu.
Itu akan menjadi sedikit lebih jelas apabila kita pergi ke contoh yang berbeza,
jadi hanya menanggung dengan saya di sana.
Sekarang kita mempunyai BAR di dalam kamus kami.
Sekarang katakan kita mempunyai perkataan Baz.
Kita mulakan dengan B, dan kita sudah mempunyai B sebagai salah satu huruf yang di dalam kamus kami.
Itu diikuti dengan A. Kami mempunyai A sudah.
Tetapi kemudian sebaliknya, kita mempunyai Z berikut.
Jadi maka elemen dalam array kami akan menjadi Z,
dan demikian maka seseorang itu akan ke titik akhir lain sah perkataan.
Jadi kita lihat bahawa apabila kita terus melalui B dan kemudian,
terdapat dua pilihan yang berbeza kini dalam kamus kita untuk perkataan yang bermula dengan B dan A.
Katakanlah kita mahu memasukkan foobar perkataan.
Kemudian kita akan membuat kemasukan di F.
F adalah nod yang mata kepada pelbagai keseluruhan.
Kita akan mendapati O, pergi ke O, O kemudian menghubungkan ke senarai keseluruhan.
Kita akan mempunyai B dan kemudian terus, kita akan mempunyai A dan kemudian R.
Jadi kemudian merentasi foobar semua jalan ke bawah sehingga foobar adalah perkataan yang betul.
Dan sebagainya maka ini akan menjadi satu perkataan yang sah.
Sekarang mengatakan perkataan seterusnya kami dalam kamus adalah sebenarnya perkataan FOO.
Kita akan mengatakan F. Apa berikut F?
Saya sebenarnya sudah mempunyai ruang untuk O, jadi saya akan terus.
Saya tidak perlu untuk membuat satu yang baru. Teruskan.
FOO adalah perkataan yang sah dalam kamus ini, maka saya akan menunjukkan
bahawa adalah sah.
Jika saya berhenti urutan saya di sana, yang akan menjadi betul.
Tetapi jika kita terus turutan kami dari FOO turun kepada B
dan hanya mempunyai FOOB, FOOB tidak adalah perkataan, dan yang tidak dinyatakan sebagai satu yang sah.
Dalam indone, anda telah setiap nod menunjukkan sama ada ia adalah satu perkataan yang sah atau tidak,
dan kemudian setiap nod juga mempunyai pelbagai 27 penunjuk nod
yang kemudian titik ke nodus diri.
>> Berikut adalah cara bagaimana anda mungkin mahu untuk menentukan ini.
Walau bagaimanapun, seperti dalam contoh jadual hash, di mana kita mempunyai kepala * nod
untuk menunjukkan permulaan senarai dihubungkan kami, kami juga akan mahu
beberapa cara mengetahui mana permulaan indone kami adalah.
Beberapa panggilan orang cuba pokok-pokok, dan itulah di mana akar datang dari.
Jadi kita mahu akar pokok kita untuk memastikan bahawa kita tinggal dibumikan
ke mana sahaja indone kami.
Kita sudah jenis pergi
cara anda boleh berfikir tentang memuatkan setiap perkataan dalam kamus.
Pada asasnya, bagi setiap perkataan, anda akan mahu untuk melelar melalui indone anda
dan mengetahui bahawa setiap unsur dalam kanak-kanak - kita dipanggil kanak-kanak dalam kes ini -
sepadan dengan surat yang berbeza, anda akan mahu untuk memeriksa nilai-nilai
pada indeks yang tertentu yang sepadan dengan huruf.
Jadi berfikir sepanjang jalan kembali ke Caesar dan Vigenere,
mengetahui bahawa setiap huruf yang anda boleh jenis peta kembali kepada indeks abjad,
pasti A melalui Z akan menjadi agak mudah untuk memetakan huruf abjad,
tetapi malangnya, koma juga merupakan watak yang diterima dalam perkataan.
Saya tidak pasti apa nilai ASCII,
jadi untuk itu jika anda mahu untuk mencari indeks untuk memutuskan sama ada anda mahu ia menjadi sama ada yang pertama
atau yang terakhir, anda akan perlu membuat cek keras berkod untuk itu
dan kemudian meletakkan bahawa dalam indeks 26, misalnya.
Jadi maka anda memeriksa nilai pada kanak-kanak [i]
mana [i] sepadan dengan apa-apa huruf yang anda berada di.
Jika itulah NULL, yang bermaksud bahawa tidak ada apa-apa surat yang mungkin
berpunca daripada urutan yang sebelumnya, supaya anda akan mahu malloc
dan membuat nod baru dan mempunyai bahawa kanak-kanak [i] titik ke
supaya anda mencipta - apabila kita memasukkan surat ke dalam segi empat tepat -
membuat kanak-kanak bukan NULL dan titik ke nod yang baru.
Tetapi jika yang tidak NULL, seperti dalam contoh kami FOO
apabila kita sudah mempunyai foobar, kita terus,
dan kita tidak pernah membuat nod baru tetapi hanya menetapkan is_word kepada true
pada akhir perkataan itu.
>> Jadi kemudian seperti sebelum ini, kerana di sini anda berurusan dengan setiap huruf pada satu masa,
ia akan menjadi lebih mudah untuk anda untuk saiz, bukannya mempunyai untuk mengira
dan pergi melalui seluruh pokok dan mengira berapa ramai anak-anak saya mempunyai
dan kemudian bercabang, mengingat berapa banyak pada sebelah kiri dan di sebelah kanan
dan perkara-perkara seperti itu, ia akan menjadi lebih mudah untuk anda
jika anda hanya menjejaki berapa banyak kata-kata anda menambah dalam
apabila anda berurusan dengan beban.
Dan demikian maka cara bahawa saiz hanya boleh kembali pembolehubah global saiz.
>> Sekarang kita datang untuk memeriksa.
Piawaian yang sama seperti sebelum ini, di mana kita mahu untuk membolehkan tidak sensitif huruf.
Juga, kita menganggap bahawa rentetan adalah hanya aksara abjad atau koma
kerana kanak-kanak adalah pelbagai sebanyak 27 lama,
jadi semua huruf abjad ditambah apostrofe.
Untuk memeriksa apa yang anda akan mahu lakukan adalah anda akan mahu bermula di akar
kerana akar akan menunjukkan kepada pelbagai yang mengandungi
semua huruf permulaan mungkin perkataan.
Anda akan bermula di sana,
dan kemudian anda pergi untuk memeriksa ini NULL nilai atau tidak,
kerana jika nilai NULL, ini bermakna bahawa kamus tidak mempunyai apa-apa nilai
yang mengandungi surat itu dalam susunan yang tertentu.
Jika ia NULL, maka ini bermakna bahawa perkataan silap eja segera.
Tetapi jika ia tidak NULL, maka anda boleh terus,
mengatakan bahawa surat pertama adalah surat yang mungkin pertama dalam perkataan,
jadi sekarang saya mahu untuk memeriksa jika surat kedua, urutan itu, adalah dalam kamus saya.
Jadi, anda akan pergi kepada indeks kanak-kanak nod pertama
dan memeriksa sama bahawa surat kedua wujud.
Kemudian anda mengulangi proses itu untuk memeriksa sama ada urutan yang sah atau tidak
dalam indone anda.
Apabila kanak-kanak nod di bahawa mata indeks untuk NULL,
anda tahu bahawa rentetan yang tidak wujud,
tetapi kemudian jika anda sampai akhir perkataan yang anda telah dimasukkan,
maka anda mahu untuk memeriksa sekarang bahawa saya telah selesai urutan ini
dan mendapati ia dalam indone saya, adalah bahawa perkataan sah atau tidak?
Dan demikian maka anda mahu untuk memeriksa bahawa, dan itulah apabila jika anda telah mendapati bahawa urutan,
maka anda mahu untuk memeriksa sama ada perkataan itu adalah sah atau tidak
kerana ingat kembali dalam kes sebelumnya yang saya menarik di mana kita terpaksa FOOB,
yang merupakan urutan sah bahawa kita mendapati tetapi tidak adalah perkataan sebenar yang sah itu sendiri.
>> Begitu juga, bagi memunggah di cuba anda mahu untuk memunggah semua nod dalam indone anda.
Maaf. Seperti jadual hash di mana dalam memunggah kita membebaskan semua nod,
cuba kita mahu juga membebaskan semua nod.
Memunggah sebenarnya akan bekerja paling mudah dari bawah ke atas
kerana ini adalah asasnya dikaitkan senarai.
Jadi, kami ingin memastikan bahawa kita memegang kepada semua nilai-nilai
dan bebas kesemua mereka jelas.
Apa yang anda akan mahu lakukan jika anda sedang bekerja dengan indone
adalah untuk pergi ke bawah dan bebas nod terendah mungkin pertama
dan kemudian pergi sehingga kepada semua orang-orang kanak-kanak dan kemudian bebas semua orang,
naik dan kemudian bebas, dan lain-lain
Jenis seperti berurusan dengan lapisan bawah yang pertama indone
dan kemudian naik atas sebaik sahaja anda telah dibebaskan segala-galanya.
Ini adalah satu contoh yang baik di mana fungsi rekursi mungkin datang dalam berguna.
Sebaik sahaja anda telah dibebaskan lapisan bawah indone anda,
maka anda memanggil memunggah di seluruh ia,
memastikan bahawa anda membebaskan setiap mini -
Anda jenis boleh menggambarkan ia sebagai cuba mini.
Jadi anda mempunyai akar anda di sini.
Saya hanya memudahkan ia jadi saya tidak perlu untuk menarik 26 daripada mereka.
Jadi anda mempunyai ini, dan kemudian ini mewakili urutan perkataan
di mana semua ini bulatan kecil adalah surat yang urutan yang sah surat.
Mari kita terus hanya sedikit lebih.
Apa yang anda akan mahu lakukan adalah percuma bawah di sini dan kemudian bebas yang satu ini
dan kemudian percuma satu ini di bawah sebelum anda membebaskan satu atas di sini
kerana jika anda sesuatu yang percuma di peringkat kedua di sini,
maka anda sebenarnya akan kehilangan nilai ini di sini.
Itulah sebabnya ia adalah penting dalam memunggah indone untuk memastikan bahawa anda membebaskan bahagian bawah dahulu.
Apa yang anda mungkin mahu lakukan adalah katakan untuk setiap nod
Saya mahu untuk memunggah semua kanak-kanak.
>> Sekarang kita telah pergi lebih memunggah untuk kaedah jadual hash serta kaedah indone,
kita akan untuk mahu melihat Valgrind.
Valgrind anda berlari dengan arahan berikut.
Anda mempunyai valgrind-v.
Anda sedang memeriksa semua kebocoran apabila anda menjalankan pengeja memandangkan teks ini tertentu
kerana pengeja perlu mengambil fail teks.
Jadi Valgrind akan menjalankan program anda, memberitahu anda berapa banyak bait anda memperuntukkan,
berapa banyak bait anda dibebaskan, dan ia akan memberitahu anda sama ada anda dibebaskan hanya cukup
atau sama ada anda tidak bebas cukup,
atau kadang-kadang anda boleh juga lebih bebas, seperti nod bebas yang sudah dibebaskan
dan sebagainya ia akan kembali anda kesilapan.
Jika anda menggunakan Valgrind, ia akan memberikan anda beberapa mesej
menunjukkan sama ada anda telah dibebaskan sama ada kurang daripada cukup, cukup,
atau lebih daripada masa yang cukup.
>> Satu sebahagian daripada pset ini, ia adalah pilihan untuk mencabar Lembaga Besar.
Tetapi apabila kita sedang berurusan dengan struktur data
ia adalah jenis menyeronokkan untuk melihat bagaimana cepat dan bagaimana cekap struktur data anda boleh.
Adakah hasil fungsi hash anda dalam banyak perlanggaran?
Atau adalah saiz data anda benar-benar besar?
Adakah ia mengambil banyak masa untuk merentasi?
Dalam log pengeja, ia output berapa banyak masa yang anda gunakan untuk beban,
untuk memeriksa, untuk menjalankan saiz, dan memunggah,
dan sebagainya yang disiarkan di Lembaga Besar,
di mana anda boleh bersaing dengan rakan sekelas anda
dan beberapa kakitangan untuk melihat siapa yang mempunyai terpantas ejaan pemeriksa.
Satu perkara yang saya ingin untuk perhatian tentang jadual hash
adalah bahawa terdapat beberapa fungsi yang agak mudah hash yang kita boleh fikirkan.
Sebagai contoh, anda mempunyai 26 baldi, dan jadi baldi setiap
sepadan dengan huruf pertama dalam perkataan,
tetapi yang akan mengakibatkan dalam jadual hash yang cukup tidak seimbang
kerana terdapat banyak kurang perkataan yang bermula dengan X daripada bermula dengan M, misalnya.
Salah satu cara untuk pergi tentang pengeja adalah jika anda ingin mendapatkan semua fungsi lain,
kemudian hanya menggunakan fungsi hash mudah dapat untuk mendapatkan kod anda berjalan
dan kemudian kembali dan mengubah saiz jadual hash anda dan definisi.
Terdapat banyak sumber di Internet untuk fungsi hash,
dan demikian bagi pset ini anda dibenarkan untuk penyelidikan fungsi hash di Internet
untuk beberapa petunjuk dan inspirasi selagi anda pastikan untuk memetik mana anda mendapat dari.
Anda dialu-alukan untuk melihat dan mentafsir beberapa fungsi hash yang anda mencari di Internet.
Kembali ke itu, anda mungkin dapat melihat jika seseorang menggunakan indone
sama ada pelaksanaan mereka adalah lebih cepat daripada jadual hash anda atau tidak.
Anda boleh mengemukakan kepada Lembaga The Big beberapa kali.
Ia akan merekodkan penyertaan anda paling terkini.
Jadi mungkin anda menukar fungsi hash anda dan kemudian menyedari bahawa ia sebenarnya banyak yang lebih cepat
atau banyak perlahan daripada sebelumnya.
Itulah sedikit cara yang menyeronokkan.
Selalu ada 1 atau 2 ahli kakitangan yang cuba untuk membuat kamus perlahan mungkin,
supaya sentiasa menyeronokkan untuk melihat.
>> Penggunaan untuk pset yang anda menjalankan pengeja dengan kamus pilihan
dan kemudian fail teks mandatori.
Secara lalai apabila anda menjalankan pengeja dengan hanya fail teks dan tidak menentukan kamus,
ia akan menggunakan fail kamus teks, satu besar
dalam folder cs50/pset5/dictionaries.
Satu yang mempunyai lebih 100,000 patah perkataan.
Mereka juga mempunyai kamus kecil yang mempunyai agak kurang perkataan
CS50 yang telah dibuat untuk anda.
Walau bagaimanapun, anda boleh sangat mudah hanya membuat kamus anda sendiri
jika anda hanya mahu bekerja dalam contoh-contoh kecil -
sebagai contoh, jika anda mahu menggunakan Pra-Pemasangan dan anda tahu nilai tertentu
yang anda mahu jadual hash anda untuk merancang.
Jadi, anda hanya boleh membuat fail teks anda sendiri hanya dengan BAR, Baz, FOO, dan foobar,
membuat bahawa dalam fail teks, memisahkan mereka masing-masing dengan baris 1,
dan kemudian membuat fail teks anda sendiri yang benar-benar hanya mengandungi mungkin 1 atau 2 perkataan
supaya anda tahu apa yang output harus.
Sebahagian daripada fail teks sampel bahawa Lembaga Besar apabila anda menghadapi cabaran akan memeriksa
Perang dan Keamanan dan novel Jane Austen atau sesuatu seperti itu.
Jadi apabila anda bermula, ia adalah lebih mudah untuk membuat fail teks anda sendiri
yang mengandungi hanya beberapa perkataan atau mungkin 10
supaya anda boleh meramalkan apa keputusan harus
dan kemudian memeriksa terhadap itu, jadi lebih contoh terkawal.
Dan sebagainya kerana kita sedang berurusan dengan meramalkan dan lukisan perkara-perkara di sekeliling,
sekali lagi saya ingin menggalakkan anda untuk menggunakan pen dan kertas
kerana ia benar-benar akan membantu anda dengan yang satu ini -
lukisan anak panah, bagaimana jadual hash atau bagaimana indone anda kelihatan,
apabila anda membebaskan sesuatu di mana anak panah akan,
anda memegang kepada cukup, adakah anda melihat link hilang
dan jatuh ke jurang memori bocor.
Jadi sila, sila cuba untuk menarik perkara-perkara yang keluar walaupun sebelum anda mendapat untuk menulis kod turun.
Lukiskan perkara supaya anda memahami bagaimana perkara akan bekerja
kerana saya jamin anda akan berjalan ke muddles penunjuk kurang di sana.
>> Semua hak.
Saya mahu ingin anda yang terbaik nasib dengan pset ini.
Ia mungkin salah satu yang paling sukar.
Oleh itu, cuba untuk memulakan awal, lukiskan perkara keluar, lukiskan perkara keluar, dan nasib baik.
Ini adalah Walkthrough 5.
>> [CS50.TV]