การเข้ารหัส Huffman: ทำไมถึงไม่มีความจำเป็นสำหรับตัวคั่น


17
Char        Code
====        ====
E           0000
i           0001
y           0010
l           0011
k           0100
.           0101
space       011
e           10
r           1100
s           1101
n           1110
a           1111

ข้อความต้นฉบับ:

ตาน่าขนลุกเห็นใกล้ทะเลสาบ

เข้ารหัส:
0000101100000110011100010101101101001111101011111111111111111111111111111111100100101 เข้ารหัส

เหตุใดจึงไม่จำเป็นต้องมีตัวคั่นในการเข้ารหัส Huffman


1
เพราะเมื่อคุณถอดรหัสค่าไบนารี่คุณจะได้รับ "ซ้ายไปขวา" ของบิตใด ๆ ที่ตรงกับค่าแรกจากข้อความต้นฉบับ เช่นในกรณีนี้คุณเห็นก้อนซ้ายสุด (0000) ตรงกับ E หากมีสัญลักษณ์ใด ๆ ที่มีค่าเป็น 000 ในรหัส char ของคุณคุณจะแทนที่ 000 ด้วยสัญลักษณ์นั้นแล้วเริ่มค้นหาอีกครั้งจากบิตที่เหลืออยู่ใน ลักษณะ "จากซ้ายไปขวา" นั่นเป็นเหตุผลที่คุณไม่จำเป็นต้องแยกจากกัน
Syed Ali Hamza

1
คำถามแสดงให้เห็นว่าจำเป็นต้องมีตัวคั่น คุณรู้อยู่แล้วว่าคุณไม่จำเป็นต้องมีตัวคั่นEerie eyes seen near lake(ดียกเว้นอักขระเว้นวรรค) แต่ตัวละครเองไม่ต้องการตัวคั่น ทำไมไม่เป็นเช่นนั้น
MSalters

พยายามที่จะถอดรหัสด้วยตัวคุณเองไม่เคยมีความกำกวมใด ๆ
njzk2

@MSalters: แต่แยกจะมักจะจำเป็นด้วยคำพูดที่ยาวตัวแปร: ≠cat cheat for mice catch eat form iceการเปรียบเทียบของคุณมีข้อบกพร่อง: จดหมายแต่ละฉบับเป็นอะตอม ตัวอักษรมีความแตกต่างเล็กน้อยและแยกกันไม่ได้ภายใน การเปรียบเทียบที่ดีกว่าคือ "ทำไมคุณสามารถอ่านสคริปต์แบบเขียนด้วยลายมือ (เมื่อเขียนด้วยลายมือ) เมื่อแต่ละคำมีความยาวเพียงหนึ่งบรรทัด, การเรียงตัวกันเป็นกลุ่ม หรือแม้แต่ส่วนหนึ่งของ) และมองเห็นตัวอักษรแต่ละตัว - ในขณะที่สตริง Huffman- เข้ารหัสเป็นซึ่งพูดพล่อยๆถ้าคุณไม่เห็นจุดเริ่มต้น
G-Man กล่าวว่า 'Reinstate Monica'

@MSalters ฉันไม่เห็นจุดที่คุณ ฉันไม่ต้องการตัวคั่นสำหรับตัวละครเพราะเราใช้การเข้ารหัสความกว้างคงที่: บล็อกที่ต่อเนื่องกันแปดบิตแต่ละตัวมีอักขระหนึ่งตัว แต่การเข้ารหัส Huffman ไม่ใช่ความกว้างคงที่ดังนั้นคำถาม
David Richerby

คำตอบ:


50

คุณไม่ต้องการตัวคั่นเนื่องจากรหัส Huffman เป็นรหัสที่ไม่มีคำนำหน้า (เช่นเดียวกับที่รู้จักกันในชื่อ "prefix codes") ซึ่งหมายความว่าไม่มี codeword เป็นคำนำหน้าของ codeword อื่น ๆ ตัวอย่างเช่น codeword สำหรับ "e" ในตัวอย่างของคุณคือ 10 และคุณจะเห็นว่าไม่มี codewords อื่นเริ่มต้นด้วยตัวเลข 10

ซึ่งหมายความว่าคุณสามารถถอดรหัสอย่างตะกละตะกลามโดยการอ่านสตริงที่เข้ารหัสจากซ้ายไปขวาและส่งออกอักขระทันทีที่คุณเห็น codeword ตัวอย่างเช่น 0, 00 และ 000 จะไม่เขียนโค้ดอะไรเลยเพื่อให้คุณอ่านบิตต่อไป เมื่อคุณอ่าน 0000 ที่เข้ารหัส "E" และเนื่องจากรหัสไม่มีคำนำหน้าคุณรู้ว่าไม่มี codeword 0000x อื่นดังนั้นตอนนี้คุณสามารถส่งออก "E" และเริ่มอ่าน codeword ถัดไป อีกครั้ง 1 ไม่ได้เข้ารหัสอะไรเลยนอกจาก 10 encodes "e" ไม่มี codewords อื่นเริ่มต้นด้วย "10" ดังนั้นคุณสามารถส่งออก "e" และอื่น ๆ


1
รหัสคำนำหน้าเป็นที่รู้จักกันทั่วไปว่าเป็นรหัสในทันที (ดูตัวอย่างองค์ประกอบของข้อมูลทฤษฎีโดย Cover & Thomas) ฉันคิดว่ารหัสคำนำหน้าขึ้นมาบ่อยกว่ารหัสที่ไม่มีคำนำหน้า
แบทแมน

3
นอกจากนี้ยังเป็นมูลค่าการกล่าวขวัญว่าเพื่อที่จะถอดรหัสลำดับของรหัส Huffman ที่ต่อกันคุณต้องได้รับขอบเขต codeword ที่ถูกต้องเพื่อเริ่มต้นด้วย หากมีใครพยายามที่จะถอดรหัสลำดับที่ขอบเขต codeword ที่ไม่ถูกต้องกระบวนการถอดรหัสจะสร้างสัญลักษณ์เอาต์พุตที่ไม่ถูกต้อง

@rwong: หากรหัส Huffman เริ่มซิงโครไนซ์ไม่ถูกต้องอาจส่งสัญญาณผิดต่อไปเรื่อย ๆ แต่เมื่อใดก็ตามที่กำหนดความยาวของสัญลักษณ์อย่างไม่ถูกต้องจำนวนสถานะผิดพลาดที่เป็นไปได้จะลดลง
supercat

@supercat ฉันเดาว่าฉันจะใช้วลีนี้ในวิธีที่ต่างกัน: ถ้าตัวถอดรหัส Huffman ถูกตั้งค่าเริ่มต้นที่ขอบเขต codeword ผิดและเริ่มการประมวลผลมีความเป็นไปได้ (ซึ่งอาจเป็นศูนย์หรืออะไรก็ได้และอาจขึ้นอยู่กับทั้งพจนานุกรมและ เนื้อหาบิตสตรีม) ว่าอาจลงจอดในขอบเขต codeword ที่ถูกต้องโดยบังเอิญในเวลา จำกัด และเมื่อเกิดเหตุการณ์ดังกล่าวจะสร้างผลลัพธ์การถอดรหัสที่ถูกต้องสำหรับสัญลักษณ์ที่ตามมา มีการวิจัยเกี่ยวกับคุณสมบัติ (ในพจนานุกรม codeword และบิตสตรีม) ที่จะรับประกันการซิงโครไนซ์นี้อีกครั้ง

@rwong: หากข้อมูลต้นฉบับถูกสุ่มโดยมีการแจกแจงว่าบิตของสตรีมจะมีความน่าจะเป็นอิสระที่จะเป็นหนึ่งหรือศูนย์ความน่าจะเป็นที่เหลือจากการซิงค์สำหรับสัญลักษณ์มากกว่า N จะลดลงอย่างทวีคูณเมื่อเพิ่ม N ข้อมูลจริงมีแนวโน้มที่จะมีรูปแบบที่อาจป้องกันการซิงโครไนซ์อีกครั้ง แต่ในทางปฏิบัติมันไม่น่าเป็นไปได้ที่ข้อผิดพลาดที่จุดเริ่มต้นของไฟล์ข้อความ 100MB จะทำให้ข้อความทั้งหมดเสียหาย 100MB
supercat

13

มันเป็นประโยชน์ที่จะจินตนาการว่ามันเป็นต้นไม้ คุณเพียงแค่สำรวจต้นไม้จนกว่าคุณจะตีโหนดใบแล้วเริ่มต้นใหม่จากราก จากอัลกอริทึมที่ทำการเข้ารหัส huffman คุณจะเห็นว่าโครงสร้างประเภทนี้ถูกสร้างขึ้นในกระบวนการ

https://en.wikipedia.org/wiki/File:HuffmanCodeAlg.png


6
สิ่งสำคัญที่นี่คือทุกคำรหัสที่ถูกต้องเป็นใบไม้ คุณต้องการตัวคั่นถ้าคุณมีสัญลักษณ์บนโหนดด้านในเช่นกัน
MvG

3

ไม่มีรหัสอื่นที่ไม่ใช่ E เริ่มต้นด้วย 0000 ไม่มีรหัสอื่นที่ไม่ใช่ฉันขึ้นต้นด้วย 0001 และอื่น ๆ ในกรณีที่รุนแรงไม่มีรหัสอื่นที่ไม่ใช่ e เริ่มต้นด้วย 01 คุณไม่มีสิ่งต่าง ๆ เช่น E = 0000, space = 000 ซึ่งคุณไม่รู้ว่าจะทำอย่างไรถ้าคุณเจอศูนย์สามตัว

ดูสตริงที่เข้ารหัสของคุณ: 0000101100000 ...

คุณอ่านศูนย์แรก คุณรู้ว่ารหัสคือหนึ่งใน E, i, y, l, k, เครื่องหมายจุลภาคหรือช่องว่าง เลขศูนย์ถัดไปหมายความว่าไม่ใช่ k, เครื่องหมายจุลภาคหรือเว้นวรรค แต่ E, i, y หรือ l เลขศูนย์ถัดไปหมายความว่ามันคือ E หรือ i เลขศูนย์ถัดไปหมายถึงมันคือ E เมื่อคุณรู้ว่ามันคือรหัสคุณรู้ว่าคุณได้ทำการแยกวิเคราะห์บิตทั้งหมดสำหรับรหัสนั้น

ถ้างั้นคุณมี 101100000 ... 1 หมายถึงคุณมี e, r, s, n หรือ a บิตถัดไปคือ 0 ดังนั้นโค้ดคือ e คุณทำกับตัวละครนั้นอีกครั้ง


-2

เราไม่สามารถใช้ตัวคั่นในการเข้ารหัส Huffman ได้เพราะตัวอักษรไบนารีที่เทียบเท่ากันทุกตัวไม่ตรงกับรหัสนำหน้าของจดหมายใด ๆ ดังนั้นเราสามารถทำได้โดยไม่ต้องใช้ตัวคั่น


3
ฉันไม่ได้พูดอย่างนั้นแล้วหากไม่มีระดับความสับสนของการปฏิเสธหลายระดับซ้อนกัน (และโดยวิธีการมันไม่ได้ว่าเราไม่สามารถใช้ตัวคั่นได้เพียงว่าเราไม่จำเป็นต้อง )
David Richerby
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.