سؤال

(هذا افتراضي إلى حد ما اعتبارا من الآن، لذلك ليس لدي الكثير من التفاصيل المقدمة.)

لدي ملف مسطح من الكلمات العشوائية (الإنجليزية)، واحد على كل سطر. أحتاج إلى كتابة برنامج فعال لحساب عدد تكرارات كل كلمة. الملف كبير (ربما حوالي 1GB)، ولكن لدي الكثير من ذاكرة الوصول العشوائي لكل شيء. يتم تخزينها على وسائل الإعلام الدائمة، لذلك سرعات القراءة بطيئة، لذلك أحتاج للتو قراءتها مرة واحدة خطيا.

وكانت أفكاري من رأسي من رأسي لاستخدام التجزئة مع الكلمات => لا. من الحوادث، أو الثلاثي مع لا. من الحوادث في عقدة النهاية. لدي ما يكفي من ذاكرة الوصول العشوائي للحصول على صفيف التجزئة، لكنني أفكر في أن الثلاثي سيكون له أبحث أسرع أو أسرع.

ما النهج سيكون أفضل؟

هل كانت مفيدة؟

المحلول

أعتقد أن Trie مع عدد الأوراق استطاع يكون أسرع.

سيتطلب أي تطبيق جدول تجزئة لائق قراءة الكلمة بالكامل، ومعالجتها باستخدام وظيفة التجزئة، وأخيرا، نظرة في الجدول.

يمكن تنفيذ ثلاثي بحيث يحدث البحث كما تقرأ الكلمة. وبهذه الطريقة، بدلا من إجراء نظرة كاملة من الكلمة، يمكنك في كثير من الأحيان تجد نفسك تخطي الشخصيات بمجرد أن أنشأت بادئة كلمة فريدة.

على سبيل المثال، إذا قرأت الأحرف: "Torto"، ستعرف Trie أن الكلمة الممكنة الوحيدة التي تبدأ بهذه الطريقة هي السلحفاة.

إذا استطعت إجراء هذا الفارغة الفارغة في البحث بشكل أسرع على كلمة أسرع من خوارزمية التجزئة التي يمكن أن تجزئة، يجب أن تكون قادرا على أن تكون أسرع.

ومع ذلك, هذا هو المجموع المبالغة. لقد بدأت منذ أن قلت إنها كانت افتراضية بحتة، احسبت أنك ترغب في نوع من الإجابة الافتراضية. الذهاب مع الحل الأكثر إميازة يقوم بالتنفيذ المهمة في فترة زمنية معقولة. عادة ما تضيع الحسابات الصغيرة عادة وقتا في ساعات الرجل أكثر مما يوفرون في ساعات المعالجة المركزية.

نصائح أخرى

كنت أستخدم كائن قاموس حيث يتم تحويل المفتاح للكلمة إلى الحالة الصغيرة والقيمة هي العدد. إذا كان القاموس لا يحتوي على الكلمة، فأضفه بقيمة 1. إذا كان يحتوي على كلمة، قم بزيادة القيمة.

نظرا لقراءة بطيئة، ربما لن تحدث أي فرق ملحوظ. سيتم تهيمن الوقت العام الكامل في الوقت المناسب اقرأ البيانات على أي حال، وهذا ما يجب أن تعمل في تحسين. بالنسبة للخوارزمية (غالبا ما تكون هيكل البيانات، حقا) في الذاكرة، استخدم ما يحدث هو الأكثر ملاءمة في اللغة التي تجدها أكثر راحة.

جدول التجزئة (إذا فعل ذلك صحيحا، وأنت قلت لك الكثير من ذاكرة الوصول العشوائي) O (1) لحساب كلمة معينة، في حين أن Trie ستكون س (ن) حيث ن هو طول الكلمة.

مع مساحة كبيرة بمساحة كبيرة بما فيه الكفاية، ستحصل على أداء أفضل بكثير من طاولة تجزئة من Trie.

أعتقد أن ثلاثي هو مبالغة في حالة استخدامك. تجزئة Word => # من الحوادث هي بالضبط ما كنت أستخدمه. حتى باستخدام لغة تفسير بطيئة مثل PERL، يمكنك من شنطة ملف 1GB بهذه الطريقة في بضع دقائق فقط. (لقد فعلت هذا من قبل.)

لدي ما يكفي من ذاكرة الوصول العشوائي للحصول على صفيف التجزئة، لكنني أفكر في أن الثلاثي سيكون له أبحث أسرع أو أسرع.

كم مرة سوف يتم تشغيل هذا الرمز؟ إذا كنت تفعل ذلك مرة واحدة فقط، فأنا أقول تحسين وقتك بدلا من وقت وحدة المعالجة المركزية الخاصة بك، ويفعل كل ما هو أسرع في التنفيذ (ضمن السبب). إذا كان لديك وظيفة مكتبة قياسية تنفذ واجهة القيمة الرئيسية، فما عليك سوى استخدام ذلك.

إذا كنت تفعل ذلك عدة مرات، فاستطع مجموعة فرعية (أو عدة مجموعات فرعية) لملف البيانات، وتقييم خياراتك. دون معرفة المزيد عن مجموعة البيانات الخاصة بك، سيكون من المشكوك أن يوصي واحدة على آخر.

استخدم بيثون!

أضف هذه العناصر إلى نوع بيانات مجموعة كما تذهب إلى السطر حسب السطر، قبل طرح ما إذا كان في جدول التجزئة. بعد أن تعرف أنه في المجموعة، ثم أضف قيمة قاموس 2، لأنك أضفته بالفعل إلى المجموعة مرة واحدة من قبل.

سيؤدي ذلك إلى بعض الذاكرة والحساب بعيدا عن السؤال من القاموس كل مرة، وبدلا من ذلك، سوف يتعامل مع كلمات فريدة من نوعها بشكل أفضل، في نهاية المكالمة فقط تفريغ كل الكلمات غير الموجودة في القاموس من مجموعة قيمة 1. (تتقاطع المجموعتين فيما يتعلق بالمجموعة)

إلى حد كبير، يعتمد ذلك على ما تريد القيام به مع البيانات بمجرد التقاطها. يرى لماذا استخدام جدول التجزئة فوق Trie (شجرة البادئة)؟

برنامج نصي بسيط بيثون:

import collections
f = file('words.txt')
counts = collections.defaultdict(int)
for line in f:
    counts[line.strip()] +=1

print "\n".join("%s: %d" % (word, count) for (word, count) in counts.iteritems())
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top