मेरा समाधान: सबसे अच्छा मामला 7.025 बिट्स / संख्या, सबसे खराब स्थिति 14.193 बिट्स / संख्या, औसत औसत 8.551 बिट्स / संख्या। स्ट्रीम-एन्कोडेड, कोई रैंडम एक्सेस नहीं।
रसिक के उत्तर को पढ़ने से पहले ही, मैंने तुरंत प्रत्येक संख्या के बीच अंतर को एन्कोडिंग करने के बारे में सोचा, क्योंकि यह छोटा होगा और अपेक्षाकृत संगत होना चाहिए, लेकिन समाधान भी सबसे खराब स्थिति को समायोजित करने में सक्षम होना चाहिए। हमारे पास 100000 नंबरों की एक जगह है जिसमें केवल 1000 नंबर हैं। पूरी तरह से एक समान फोन बुक में, प्रत्येक संख्या पिछले संख्या से 100 से अधिक होगी:
55555-12 3 45
55555-12 4 45
55555-12 5 45
यदि ऐसा होता, तो संख्याओं के बीच अंतर को सांकेतिक रूप से अंकित करने के लिए शून्य भंडारण की आवश्यकता होती, क्योंकि यह एक ज्ञात स्थिरांक है। दुर्भाग्य से, संख्याएं 100 के आदर्श चरणों से भिन्न हो सकती हैं। मैं 100 के आदर्श वेतन वृद्धि से अंतर को सांकेतिक शब्दों में बदलना होगा, ताकि यदि दो आसन्न संख्याएं 103 से भिन्न हों, तो मैं संख्या 3 को सांकेतिक शब्दों में बदलना चाहूंगा और यदि दो आसन्न संख्याएं 92 से भिन्न हैं, तो मैं एनकोड करना होगा -8। मैं 100 " विचरण " के एक आदर्श वेतन वृद्धि से डेल्टा को बुलाता हूं ।
विचरण -99 (यानी दो लगातार संख्या) से लेकर 99000 तक हो सकता है (संपूर्ण फोनबुक में 00000 नंबर ... 00999 और एक अतिरिक्त दूर-दूर की संख्या 99999 है), जो 99100 संभावित मूल्यों की एक सीमा है।
यदि मैं बड़े अंतरों (जैसे प्रोटोजोफ ) का सामना करूं तो सबसे आम अंतरों को एनकोड करने और भंडारण का विस्तार करने के लिए एक न्यूनतम भंडारण आवंटित करना चाहता हूं।varint
) का । मैं सात बिट्स, छह भंडारण के लिए और अंत में एक अतिरिक्त फ्लैग बिट का उपयोग करने के लिए इंगित करता हूं कि यह विचरण वर्तमान एक के बाद एक अतिरिक्त चंक के साथ संग्रहीत किया गया है, अधिकतम तीन चंक्स तक (जो अधिकतम प्रदान करेगा 3 * 6 = 18 बिट्स स्टोरेज, जो कि 262144 संभावित मान हैं, जो संभावित वेरिएंस (99100) की संख्या से अधिक हैं। एक उठाए गए झंडे का अनुसरण करने वाले प्रत्येक अतिरिक्त चंक में उच्च महत्व के बिट्स होते हैं, इसलिए पहला चंक हमेशा बिट्स 0- होता है। 5, वैकल्पिक दूसरी विखंडू में 6-11 बिट्स हैं, और वैकल्पिक तीसरे चंक में बिट्स 12-17 हैं।
एक एकल चंक भंडारण के छह बिट्स प्रदान करता है जो 64 मूल्यों को समायोजित कर सकता है। मैं उस सिंगल चंक (यानी -32 से +31 तक के वेरिएंट) में फिट होने के लिए 64 सबसे छोटे वेरिएंट को मैप करना चाहता हूं, इसलिए मैं ProtoBuf ZigZag एन्कोडिंग का उपयोग करूँगा, -99 के वेरिएंट से +98 तक (क्योंकि कोई ज़रूरत नहीं है) -99 से परे एक नकारात्मक विचरण के लिए), जिस बिंदु पर मैं नियमित एन्कोडिंग पर जाऊंगा, 98 से ऑफसेट:
विचरण | एन्कोड किया गया मान
----------- + ----------------
0 | 0
-1 | 1
1 | 2
-2 | 3
2 | 4
-3 | 5
3 | 6
... | ...
-31 | 61
31 | 62
-32 | 63
----------- | --------------- 6 बिट्स
32 | 64
-33 | 65
33 | 66
... | ...
-98 | 195
98 | 196
-99 | 197
----------- | --------------- जिगजैग का अंत
100 | 198
101 | 199
... | ...
3996 | 4094
3997 | 4095
----------- | --------------- १२ बिट्स
3998 | 4096
3999 | 4097
... | ...
262045 | 262,143
----------- | --------------- १। बिट्स
अतिरिक्त चंक को इंगित करने के लिए झंडे सहित बिटियन के रूप में कैसे भिन्न होंगे, इसके कुछ उदाहरण:
विचरण | एन्कोडेड बिट्स
----------- + ----------------
0 | 000000 ०
5 | 001010 0
-8 | ००११११ ०
-32 | ११११११ ०
32 | 000000 1 000001 0
-99 | 000101 1 000011 0
177 | 010011 1 000100 0
14444 | 001110 1 100011 1 000011 0
इसलिए नमूना फोन बुक के पहले तीन नंबर बिट्स की एक धारा के रूप में इनकोड किए जाएंगे:
BIN 000101001011001000100110010000011001 000110 1 010110 1 00001 0
PH # 55555-12345 55555-12448 55555-12491
पीओएस 1 2 3
सबसे अच्छी स्थिति , फोन बुक कुछ हद तक समान रूप से वितरित की जाती है और ऐसे दो फोन नंबर नहीं होते हैं, जिनमें 32 से अधिक का विचरण हो, इसलिए यह कुल संख्या के लिए 7 बिट प्रति प्लस और 32 बिट्स का उपयोग करेगा, जो कि कुल संख्या 32 + 7 * 999 के लिए होगा। = 7025 बिट्स ।
एक मिश्रित परिदृश्य , जहां 800 फोन नंबरों का विचरण एक चंक (800 * 7 = 5600) के भीतर फिट होता है, 180 नंबर दो विखंडू में फिट होते हैं (180 * 2 * 7 = 2520) और 19 नंबर तीन विखंडू में फिट होते हैं (20 * 3) * 7 = 399), प्रारंभिक 32 बिट्स, 8551 बिट्स योग ।
सबसे खराब स्थिति , 25 संख्याएँ तीन विखंडू में फिट होती हैं (25 * 3 * 7 = 525 बिट्स) और शेष 974 संख्याएँ दो विखंडू (974 * 2 * 7 = 13636 बिट्स) में फिट होती हैं, साथ ही एक ग्रैंड के लिए पहली संख्या के लिए 32 बिट्स कुल14193 बिट्स ।
एन्कोडेड नंबरों की राशि |
1-चंक | 2-विखंडू | 3-विखंडू | कुल बिट्स
--------- + ---------- + ---------- + ------------
999 | 0 | 0 | 7025
800 | 180 | 19 | 8551
0 | 974 | 25 | 14,193
मैं चार अतिरिक्त अनुकूलन देख सकता हूं जो आवश्यक स्थान को और कम करने के लिए किया जा सकता है:
- तीसरे चंक को पूरे सात बिट्स की जरूरत नहीं है, यह सिर्फ पांच बिट्स और बिना फ्लैग बिट के हो सकता है।
- प्रत्येक चंक के लिए सर्वोत्तम आकारों की गणना करने के लिए संख्याओं का एक प्रारंभिक पास हो सकता है। हो सकता है कि एक निश्चित फोनबुक के लिए, यह सबसे अच्छा होगा कि पहले चंक में 5 + 1 बिट्स हों, दूसरा 7 + 1 और तीसरा 5 + 1 हो। यह आगे आकार को कम से कम 6 * 999 + 32 = 6026 बिट्स, प्लस तीन बिट्स के दो सेटों को 1 और 2 के आकार को संग्रहीत करने के लिए करेगा (कुल मिलाकर 3 बिट्स का आकार शेष 16 बिट्स के लिए शेष है) 6032 बिट्स की!
- वही प्रारंभिक पास डिफ़ॉल्ट 100 की तुलना में बेहतर प्रत्याशित वृद्धि की गणना कर सकता है। हो सकता है कि 55555-50000 से शुरू होने वाली फोन बुक हो, और इसलिए इसकी आधी संख्या सीमा हो, इसलिए अपेक्षित वेतन वृद्धि 50 होनी चाहिए। या हो सकता है कि कोई गैर-रैखिक हो वितरण (मानक विचलन शायद) और कुछ अन्य इष्टतम अपेक्षित वेतन वृद्धि का उपयोग किया जा सकता है। यह विशिष्ट विचरण को कम करेगा और उपयोग करने के लिए एक छोटा सा पहला हिस्सा भी अनुमति दे सकता है।
- फोन पास को विभाजित करने की अनुमति देने के लिए पहले पास में आगे का विश्लेषण किया जा सकता है, प्रत्येक विभाजन के पास अपनी अपेक्षित वृद्धि और चंक आकार के अनुकूलन होते हैं। यह फोन बुक के कुछ अत्यधिक समरूप भागों के लिए एक छोटे से पहले चंक आकार की अनुमति देता है (भस्म बिट्स की संख्या को कम करता है) और गैर-समान भागों के लिए बड़ा हिस्सा आकार (निरंतरता झंडे पर व्यर्थ बिट्स की संख्या को कम करना)।