ইউনিকোড স্ট্রিংয়ের জন্য দক্ষ ট্রি প্রয়োগকরণ


12

আমি একটি দক্ষ স্ট্রিং ট্রাই বাস্তবায়ন খুঁজছি। বেশিরভাগ ক্ষেত্রেই আমি এর মতো কোড পেয়েছি:

জাভাতে রেফারেন্সিয়াল বাস্তবায়ন (উইকিপিডিয়া প্রতি)

বেশিরভাগ দুটি কারণে আমি এই বাস্তবায়নগুলি অপছন্দ করি:

  1. তারা কেবল 256 ASCII অক্ষর সমর্থন করে। আমাকে সিরিলিকের মতো জিনিসগুলি coverাকতে হবে।
  2. এগুলি অত্যন্ত স্মৃতিশক্তি অযোগ্য ine

প্রতিটি নোডে 256 টি রেফারেন্সের অ্যারে থাকে যা জাভাতে একটি 64 বিট মেশিনে 4096 বাইট। এই নোডের প্রতিটিতে 4096 বাইটের প্রতিটি রেফারেন্স সহ 256 টি পর্যন্ত সাবনোড থাকতে পারে। সুতরাং প্রতিটি ASCII 2 টি অক্ষরের স্ট্রিংয়ের জন্য একটি সম্পূর্ণ ট্রাইয়ের জন্য 1MB এর চেয়ে কিছু বেশি প্রয়োজন। তিনটি চরিত্রের স্ট্রিং? 256MB কেবল নোডগুলিতে অ্যারে করার জন্য। ইত্যাদি।

অবশ্যই আমার ট্রিতে ১ million মিলিয়ন তিনটি চরিত্রের স্ট্রিং থাকার ইচ্ছা নেই, তাই প্রচুর স্থান স্রেফ নষ্ট হয়ে গেছে। এগুলির বেশিরভাগ অ্যারে কেবল নাল রেফারেন্স হিসাবে তাদের ক্ষমতা সন্নিবেশিত কীগুলির প্রকৃত সংখ্যাকে অতিক্রম করে। এবং যদি আমি ইউনিকোড যুক্ত করি তবে অ্যারেগুলি আরও বড় হয় (জাভাতে 256 এর পরিবর্তে চরের 64k মান রয়েছে)।

স্ট্রিংগুলির জন্য দক্ষ ট্রাই করার কোনও আশা আছে কি? আমি এই ধরণের বাস্তবায়নের তুলনায় বেশ কয়েকটি উন্নতি বিবেচনা করেছি:

  • রেফারেন্সের অ্যারে ব্যবহারের পরিবর্তে, আমি আদিম পূর্ণসংখ্যার ধরণের অ্যারে ব্যবহার করতে পারি, যা নোডগুলির রেফারেন্সের অ্যারেটিতে সূচি দেয় যার আকারটি প্রকৃত নোডের সংখ্যার কাছাকাছি।
  • আমি স্ট্রিংগুলিকে 4 টি বিট অংশে বিভক্ত করতে পারি যা গভীর গাছের দামে 16 মাপের নোড অ্যারেগুলিকে অনুমতি দেয়।

উত্তর:


2

আপনি এই ট্রাইটি কীসের জন্য ব্যবহার করছেন? আপনি যে শব্দগুলি ধরে রাখার পরিকল্পনা করছেন তার মোট সংখ্যাটি কী এবং তাদের উপাদানগুলির চরিত্রের স্বল্পতা কত? এবং সর্বাধিক গুরুত্বপূর্ণ, একটি ত্রিও কি উপযুক্ত (শব্দের তালিকার উপসর্গের একটি সাধারণ মানচিত্রের বিপরীতে)?

একটি মধ্যবর্তী টেবিল সম্পর্কে আপনার ধারণা এবং সূচকগুলির সাথে পয়েন্টারগুলি প্রতিস্থাপনের কাজ করবে তবে শর্ত থাকে যে আপনার কাছে অপেক্ষাকৃত ছোট শব্দের সংক্ষিপ্ত সেট এবং একটি বিরল অক্ষর সেট রয়েছে। অন্যথায় আপনি আপনার মধ্যবর্তী টেবিলের স্থান অদৃশ্য হয়ে যাওয়ার ঝুঁকি নিয়েছেন। এবং আপনি যদি শব্দগুলির একটি খুব ছোট সেটটি না দেখেন তবে আপনি সত্যিই এত বেশি স্থানটি সংরক্ষণ করতে পারবেন না: 32-বিট মেশিনে একটি রেফারেন্সের জন্য স্বল্প বনাম 4 বাইটের জন্য 2 বাইট। যদি আপনি একটি -৪-বিট জেভিএম চালিয়ে যাচ্ছেন তবে সঞ্চয়ীকরণ আরও বেশি হবে।

চরিত্রগুলিকে 4-বিট খণ্ডে ভাঙ্গার বিষয়ে আপনার ধারণা সম্ভবত আপনাকে বেশি পরিমাণে সাশ্রয় করতে পারবেন না, যদি না আপনার প্রত্যাশিত সমস্ত অক্ষর অত্যন্ত সীমিত পরিসরে থাকে (সম্ভবত ইউক্রোড ইউএস-এএসসিআই-তে সীমাবদ্ধ শব্দের জন্য ঠিক আছে, সাধারণ ইউনিকোড কর্পাসের সাথে সম্ভবত না )।

আপনার যদি বিরল অক্ষর সেট থাকে, তবে এটি HashMap<Character,Map<...>>হতে পারে আপনার সেরা বাস্তবায়ন। হ্যাঁ, প্রতিটি এন্ট্রি অনেক বড় হবে, তবে আপনার যদি অনেক এন্ট্রি না রাখেন তবে আপনি সামগ্রিক জয় পাবেন। (একটি পার্শ্ব নোট হিসাবে: আমি সর্বদা মনে করি এটি মজার বিষয় ছিল যে ট্রাইজে উইকিপিডিয়া নিবন্ধটি দেখিয়েছিল - সম্ভবত এখনও তা করে - একটি হ্যাশড ডেটা কাঠামোর উপর ভিত্তি করে একটি উদাহরণ, সেই পছন্দের স্থান / সময় ট্রেড অফকে সম্পূর্ণ উপেক্ষা করে)

শেষ অবধি, আপনি একটি ট্রিও পুরোপুরি এড়াতে চাইতে পারেন। যদি আপনি কোনও মানব ভাষায় সাধারণ শব্দের একটি কর্পাসের দিকে লক্ষ্য রাখেন (সক্রিয় ব্যবহারে 10,000 শব্দ, 4-8 অক্ষরের দীর্ঘ শব্দ সহ) আপনি সম্ভবত একটির সাথে আরও ভাল হবেন HashMap<String,List<String>, যেখানে মূল উপগ্রহটি পুরো is


- 32-বিট-এ 8 বাইট, 64-বিট মেশিনে 16 বাইট - এটি স্বতঃসিদ্ধ কার্যকারিতার জন্য - স্ট্রিংয়ের বেশিরভাগ অক্ষর ASCII সীমার মধ্যে থাকে তবে কয়েকটি কেন্দ্রীয় ইউরোপীয় অক্ষর নিক্ষেপ করা হয় This এজন্য আমি আরও ছোট শাখা চাইছিলাম 256 এর চেয়ে বেশি, কারণ এটি প্রচুর পরিমাণে অক্ষর কেটে ফেলবে। লিখতে ও ব্যবহার করা খুব সহজ হলেও, আমি হ্যাশম্যাপ <স্ট্রিং, তালিকা <স্ট্রিং>> আরও ভাল বা দ্রুত বা কম স্মৃতিশক্তি গ্রহণ করে দেখছি না। তবে আমি হ্যাশম্যাপ <চরিত্র, মানচিত্র> ধারণাটির জন্য গ্রহণ করব। 128 এর বেশি অক্ষরের জন্য ঠিক আছে (আমার ক্ষেত্রে বিরল - চীনা পাঠ্যের পক্ষে খারাপ হবে)।
রকএল

4

আপনি যদি ইউটিএফ 8 এ স্ট্রিংগুলি এনকোড করে থাকেন তবে আপনি স্ট্যান্ডার্ড 256 ব্রাঞ্চিং ট্রাই ব্যবহার করতে পারেন এবং ইউনিকোডের সাথে সামঞ্জস্যপূর্ণ হতে পারেন

এছাড়াও আপনার লক্ষ করা উচিত যে সম্ভাব্য 128 এসকিআই অক্ষরের মধ্যে কেবল 70 বা তার বেশি অক্ষর (যা সমস্ত ইউটিএফ 8-এ 1 বাইটে এনকোড করে) পাওয়া যায় আপনি এটির জন্য খুব বেশি ভারীমাইজ করতে পারেন (যেমন অব্যবহৃত নিয়ন্ত্রণের অক্ষরের জায়গায় সাধারণ ডিগ্রাফগুলি অন্তর্ভুক্ত করুন) )


আমি জানি যে ইউটিএফ 8 এর মতো প্রতিনিধিত্ব করা যায়। তবে এটি এখনও মেমরির ব্যবহারের সমাধান করে না যা এখনও অনেক বেশি। অক্ষরগুলি বেসিক 256 পরিসরে অদলবদল করতে বেশ কিছুটা সুইচ বাক্য লাগবে, আমি সন্দেহ করি এটির পক্ষে এটি উপযুক্ত হবে। ইউটিএফ -8 যতদূর যায় ... এটি আসলে এটি এখনই আমি ভাবছি an জাভা স্ট্রিং ইউটিএফ -16 অক্ষর ব্যবহার করে, যা আমি সহজেই পেতে পারি, আমি বাইট দ্বারা এই বাইটটি এনকোড করতে পারি। অথবা আমি ইউটিএফ -8 এ রূপান্তর করতে এবং এটি ব্যবহার করতে পারি। এই মুহুর্তে এটি আমার কাছে স্পষ্ট নয় যদি ইউটিএফ -16 থেকে ইউটিএফ -8 এ রূপান্তরকরণের ব্যয়টি নিষিদ্ধ বা না হয়।
রকএল

আপনি বেশিরভাগ সময় এটি ব্যবহার করে কোন ভাষাটি কল্পনা করেন? সমস্ত কিছুর জন্য অপ্টিমাইজ করার চেষ্টা করা অসম্ভব (বা এটি ইতিমধ্যে হয়ে গিয়েছিল) তাই সাধারণ মামলার জন্য অনুকূলিত করুন
রাচেট ফ্রিক

1
এটি খুব কম ব্যবহারের ক্ষেত্রে একটি যেখানে ইউটিএফ -8 এর চেয়ে সিইএসইউ -8 বেশি পছন্দনীয়: এখানে বিশাল সুবিধা হ'ল এটি কোনও ইউটিএফ -8 কোডডপয়েন্ট থেকে সংশ্লিষ্ট সিইএসইউ -8 কোডপয়েন্টের কাছে পৌঁছানো তুচ্ছ (যদিও আপনার প্রয়োজন হবে) সংশ্লিষ্ট ইউটিএফ -8 কোডপয়েন্টে পেতে 1-2 ইউটিএফ -16 কোডপয়েন্টগুলি ডিকোড করতে)।
জোচিম সউর

1
@ratchetfreak জাভা যদিও আমি মনে করি প্রশ্নটি বেশিরভাগ ভাষায় সাধারণীকরণ করা যায়। আমি সি তে অনুমান করি যে আপনি byte*বিটওয়াইস ট্রাইতে যে কোনও ধরণের এনকোড করার জন্য কেবল পয়েন্টার নিক্ষেপ করতে পারেন।
রকএল

@ উমাদ আমার অর্থ কী কী ইনপুট স্ট্রিংগুলি থাকবে (ইংরাজী, ফরাসী, জার্মান, ...)
রাচেট ফ্রিক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.