2012-06-04 4 views
5

Tôi muốn nén nhiều chuỗi nhỏ (khoảng 75-100 độ dài C# chuỗi). Tại thời điểm từ điển được tạo, tôi đã biết tất cả các chuỗi ngắn (gần một nghìn tỷ). Sẽ không có chuỗi ngắn bổ sung nào trong tương lai. Tôi cần thêm chính xác một chuỗi mà không giải nén các chuỗi khác.Nén các chuỗi nhỏ, với những gì để tạo từ điển bên ngoài?

Bây giờ tôi đang tìm kiếm một thư viện hoặc cách tốt nhất để làm như sau:

  1. Tạo một từ điển sử dụng tất cả các chuỗi Tôi có
  2. Sử dụng từ điển này để nén mỗi chuỗi
  3. một cách để nén một chuỗi bằng từ điển từ 1.

Tôi đã tìm thấy good related question, nhưng điều này không cụ thể. Có lẽ có cái gì đó cho C# Tôi không biết, hoặc một thư viện ưa thích hoặc ai đó đã làm điều đó. Đó là lý do tôi hỏi câu hỏi này.

EDIT:

Với từ điển mà tôi đang nói về những điều như thế này: http://en.wikipedia.org/wiki/Dictionary_coder Nhưng tất cả những gì giúp để có được những chuỗi ngắn hơn. Các chuỗi là các tin nhắn văn bản ngắn trong các ngôn ngữ và URL khác nhau (30%/70%). Không cần các chuỗi được nén là con người có thể đọc được. Nó sẽ được lưu trữ trong các tập tin nhị phân.

+0

Loại dữ liệu nào có trong chuỗi? (chủ yếu là ASCII? Chữ cái ngẫu nhiên? GUID?) – Cameron

+0

Theo từ điển, bạn có nghĩa là lớp .NET 'Dictionary' lưu trữ cặp khóa-giá trị không? Các chuỗi có được sử dụng làm khóa hoặc giá trị trong từ điển của bạn không? Nếu các chuỗi chỉ là giá trị, các phím sẽ là gì? –

+0

chủ yếu là ascii, không phải ngẫu nhiên. Giống như tin nhắn văn bản ngắn, câu và url. – Chris

Trả lời

1

Nếu có một nghìn tỷ dây và không còn nữa, thì mỗi chuỗi có thể được biểu diễn bằng 40 bit (5 byte). Tất cả những gì bạn cần là một cách để sử dụng 5 byte làm chỉ mục cho hàng nghìn tỷ.

Làm thế nào để bạn biết tất cả nghìn tỷ chuỗi? Nếu máy nén và bộ giải nén đều có quyền truy cập vào tất cả nghìn tỷ chuỗi hoặc nếu có cách để đặt hàng và tạo lại các chuỗi, thì tất cả những gì bạn cần là chỉ mục.

Nếu bạn không thể tìm cách lập chỉ mục các chuỗi, thì bạn có thể lấy một tập con của các chuỗi và sử dụng chúng làm từ điển cho máy nén.Chỉ cần lấy mẫu đại diện nhất (bạn cần phải tìm ra những gì có thể làm cho một số chuỗi phổ biến hơn các chuỗi khác hoặc đại diện của các chuỗi khác) và nối chúng vào một từ điển 32K. Khoảng 400 nghìn tỷ dây của bạn. Sau đó, deflateSetDictionary zlib của ngày cuối nén và inflateSetDictionary vào cuối giải nén, cả hai đều sử dụng chính xác cùng một từ điển 32K. Điều đó sẽ cung cấp nén tốt trên các chuỗi ngắn.

+0

Cách đầu tiên không áp dụng trong miền đặc biệt. Nhưng thứ hai (deflateSetDictionary) có vẻ rất hứa hẹn. Tôi có một câu hỏi liên quan đến từ điển: Hãy nói rằng tôi có trong Từ điển của tôi các giá trị sau: "CDEFGHIJK" và "ABC" và các từ điển khác. Khi tôi nén chuỗi "ABCDEFGHIJK" nó sẽ sử dụng giá trị "ABC" và sau đó không "CDEFGHIJK" từ từ điển của tôi, hoặc nó sẽ không sử dụng "ABC" nhưng nó sẽ sử dụng "CDEFGHIJK" (điều gì sẽ tốt hơn)? – Chris

+0

Một câu hỏi bổ sung: Bạn đã viết tôi nên sử dụng 400 trong số hàng nghìn tỷ của tôi. Kích thước của từ điển là 32K hay số lượng giá trị? Dường như nó là một mảng byte sẽ vô hiệu hóa các chuỗi, có chuỗi có thể xảy ra nhất ở cuối. – Chris

+0

xì hơi sẽ tìm và sử dụng chuỗi dài hơn để khớp. Nói chung thì tốt hơn. Nếu bạn biết chuỗi nào có thể phổ biến hơn, bạn nên đặt các chuỗi đó vào cuối từ điển và ít phổ biến hơn khi bắt đầu. (Điều này dẫn đến ít bit trung bình hơn cho việc mã hóa khoảng cách.) 32K là kích thước của từ điển. Vì vậy, 400 chuỗi chỉ là một ước tính sơ bộ từ "75-100" của bạn về số lượng phù hợp. –

1

tôi đã không sử dụng nó, nhưng Smaz âm thanh đầy hứa hẹn cho việc này ...

Smaz là một thư viện nén đơn giản phù hợp cho nén rất chuỗi ngắn. Thư viện nén mục đích chung sẽ xây dựng trạng thái cần thiết để nén dữ liệu động, để có thể nén mọi loại dữ liệu. Đây là một ý tưởng rất hay, nhưng không phải cho một vấn đề cụ thể: nén các chuỗi nhỏ sẽ không hoạt động.

Smaz thay vào đó là không tốt cho nén dữ liệu mục đích chung, nhưng có thể nén văn bản bằng 40-50% trong trường hợp trung bình (chỉ hoạt động tốt hơn với tiếng Anh), và có thể thực hiện một chút nén cho HTML và cũng là url. Điểm quan trọng là Smaz có thể nén ngay cả các chuỗi gồm hai hoặc ba byte!

Ví dụ: chuỗi "the" được nén thành một byte đơn.

Vì văn bản được viết bằng C, hãy kiểm tra Bart De Smet's example for interoping with C through C#.

+0

Nếu chúng là các chuỗi văn bản ngắn của một ngôn ngữ đã biết; smaz âm thanh lý tưởng; nó sẽ nén các động từ thông dụng ngắn (như, anh, cô, nó, tôi, vv) thành các chuỗi byte rất ngắn. Nếu các chuỗi bị mất mẫu đó, bạn thậm chí có thể kết thúc thấy rằng các chuỗi đã nén của bạn dài hơn! –

+0

Bạn có thể thử dịch nó, hoặc sử dụng interop (xem câu trả lời cập nhật của tôi). –

+0

Phiên bản C# tại đây: https://github.com/poulfoged/SentenceCompression – gameweld