Tôi đang tìm kiếm một thuật toán để nén các chuỗi văn bản nhỏ: 50-1000 byte (tức là các URL). Thuật toán nào hoạt động tốt nhất cho việc này?
tinyurls
hoặc một cái gì đó để làm với không gian lưu trữ?
Tôi đang tìm kiếm một thuật toán để nén các chuỗi văn bản nhỏ: 50-1000 byte (tức là các URL). Thuật toán nào hoạt động tốt nhất cho việc này?
tinyurls
hoặc một cái gì đó để làm với không gian lưu trữ?
Câu trả lời:
Kiểm tra Smaz :
Smaz là một thư viện nén đơn giản phù hợp để nén các chuỗi rất ngắn.
string:orig_size:compr_size:space_savings
): This is the very end of it.:27:13:52%
, Lorem ipsum dolor sit amet:26:19:27%
, Llanfairpwllgwyngyll:20:17:15%
, aaaaaaaaaaaaa:13:13:0%
, 2BTWm6WcK9AqTU:14:20:-43%
,XXX:3:5:-67%
Huffman có một chi phí tĩnh, bảng Huffman, vì vậy tôi không đồng ý đó là một lựa chọn tốt.
Có những phiên bản thích ứng loại bỏ điều này, nhưng tốc độ nén có thể bị ảnh hưởng. Trên thực tế, câu hỏi bạn nên đặt ra là "thuật toán nào để nén các chuỗi văn bản với các đặc điểm này". Ví dụ, nếu dự kiến lặp lại dài, Mã hóa Run-Lengh đơn giản có thể là đủ. Nếu bạn có thể đảm bảo rằng chỉ có các từ tiếng Anh, dấu cách, dấu chấm câu và các chữ số không thường xuyên sẽ xuất hiện, thì Huffman với bảng Huffman được xác định trước có thể mang lại kết quả tốt.
Nói chung, các thuật toán của gia đình Lempel-Ziv có khả năng nén và hiệu năng rất tốt và các thư viện cho chúng rất nhiều. Tôi sẽ đi với điều đó.
Với thông tin rằng những gì đang được nén là URL, thì tôi khuyên bạn nên trước khi nén (với bất kỳ thuật toán nào có sẵn dễ dàng), bạn CODIFY chúng. Các URL tuân theo các mẫu được xác định rõ và một số phần của nó có khả năng dự đoán cao. Bằng cách sử dụng kiến thức này, bạn có thể mã hóa các URL thành một cái gì đó nhỏ hơn để bắt đầu và những ý tưởng đằng sau mã hóa Huffman có thể giúp bạn ở đây.
Ví dụ: dịch URL thành luồng bit, bạn có thể thay thế "http" bằng bit 1 và bất cứ thứ gì khác bằng bit "0" theo sau là Procotol thực tế (hoặc sử dụng bảng để nhận các giao thức phổ biến khác, như https, ftp, tập tin). ": //" có thể được loại bỏ hoàn toàn, miễn là bạn có thể đánh dấu sự kết thúc của giao thức. V.v. Hãy đọc về định dạng URL và suy nghĩ về cách chúng có thể được mã hóa để chiếm ít không gian hơn.
Tôi không có mã trong tay, nhưng tôi luôn thích cách tiếp cận xây dựng bảng tra cứu 2D có kích thước 256 * 256 ký tự ( RFC 1978 , Giao thức nén dự đoán PPP ). Để nén một chuỗi, bạn lặp qua từng char và sử dụng bảng tra cứu để lấy char tiếp theo 'dự đoán' bằng cách sử dụng char hiện tại và trước đó làm chỉ mục vào bảng. Nếu có một trận đấu bạn viết 1 bit đơn, nếu không hãy viết 0, char và cập nhật bảng tra cứu với char hiện tại. Cách tiếp cận này về cơ bản duy trì một bảng tra cứu động (và thô) của nhân vật tiếp theo có thể xảy ra nhất trong luồng dữ liệu.
Bạn có thể bắt đầu với một bảng tra cứu bằng 0, nhưng thật ra nó hoạt động tốt nhất trên các chuỗi rất ngắn nếu nó được khởi tạo với ký tự có khả năng nhất cho mỗi cặp ký tự, ví dụ, đối với ngôn ngữ tiếng Anh. Miễn là bảng tra cứu ban đầu giống nhau để nén và giải nén, bạn không cần phải phát nó vào dữ liệu nén.
Thuật toán này không cho tỷ lệ nén tuyệt vời, nhưng nó cực kỳ tiết kiệm với tài nguyên bộ nhớ và CPU và cũng có thể hoạt động trên một luồng dữ liệu liên tục - bộ giải nén duy trì bản sao của bảng tra cứu khi giải nén, do đó bảng tra cứu điều chỉnh loại dữ liệu được nén.
Bất kỳ thuật toán / thư viện nào hỗ trợ từ điển đặt trước, ví dụ zlib .
Bằng cách này, bạn có thể xử lý trình nén với cùng loại văn bản có khả năng xuất hiện trong đầu vào. Nếu các tệp tương tự nhau theo một cách nào đó (ví dụ: tất cả các URL, tất cả các chương trình C, tất cả các bài đăng StackOverflow, tất cả các bản vẽ nghệ thuật ASCII) thì các chuỗi con nhất định sẽ xuất hiện trong hầu hết hoặc tất cả các tệp đầu vào.
Mọi thuật toán nén sẽ tiết kiệm dung lượng nếu cùng một chuỗi con được lặp lại nhiều lần trong một tệp đầu vào (ví dụ: "the" trong văn bản tiếng Anh hoặc "int" trong mã C.)
Nhưng trong trường hợp URL, một số chuỗi nhất định (ví dụ: " http: // www .", ".Com", ".html", ".aspx" thường sẽ xuất hiện một lần trong mỗi tệp đầu vào. Vì vậy, bạn cần chia sẻ chúng giữa các tệp. bằng cách nào đó thay vì có một lần xuất hiện nén trên mỗi tệp. Đặt chúng vào một từ điển đặt sẵn sẽ đạt được điều này.
Mã hóa Huffman thường hoạt động tốt cho việc này.
Nếu bạn đang nói về việc thực sự nén văn bản không chỉ rút ngắn thì Deflate / gzip (trình bao bọc xung quanh gzip), zip hoạt động tốt cho các tệp và văn bản nhỏ hơn. Các thuật toán khác có hiệu quả cao cho các tệp lớn hơn như bzip2, v.v.
Wikipedia có một danh sách thời gian nén. (tìm kiếm để so sánh hiệu quả)
Name | Text | Binaries | Raw images
-----------+--------------+---------------+-------------
7-zip | 19% in 18.8s | 27% in 59.6s | 50% in 36.4s
bzip2 | 20% in 4.7s | 37% in 32.8s | 51% in 20.0s
rar (2.01) | 23% in 30.0s | 36% in 275.4s | 58% in 52.7s
advzip | 24% in 21.1s | 37% in 70.6s | 57& in 41.6s
gzip | 25% in 4.2s | 39% in 23.1s | 60% in 5.4s
zip | 25% in 4.3s | 39% in 23.3s | 60% in 5.7s
Bạn có thể muốn xem sơ đồ nén tiêu chuẩn cho Unicode .
SQL Server 2008 R2 sử dụng nội bộ và có thể đạt được mức nén lên tới 50%.