जावा में लाभ फ़िल्टर प्रदर्शन


9

मुझे जावा-आधारित वेब एप्लिकेशन में उपयोगकर्ताओं के सबमिशन से अपवित्रता को फ़िल्टर करने की आवश्यकता है। क्लाइंट को Scunthorpe Problem और Clbuttic Problem दोनों के बारे में पता है और उसने परिणाम को स्वीकार कर लिया है। कृपया, मैं सेंसरशिप की कमी के गुणों पर बहस नहीं करना चाहता।

डेटा के दो बिट्स हैं:

  1. उपयोगकर्ता का सबमिशन, जिसमें संभावित रूप से 500 शब्द या तो हो सकते हैं;
  2. एकल-स्तंभ डेटाबेस तालिका जिसमें शब्द अस्वीकृत हैं। इस तालिका में कई हजारों रिकॉर्ड हो सकते हैं।

वर्तमान समाधान मुझे गलत लगता है:

  1. संपूर्ण तालिका को एक सिंगलटन में स्टार्टअप पर स्थिर स्ट्रिंग [] में लोड किया जाता है (इस प्रकार मेमोरी में रहता है)।
  2. प्रत्येक उपयोगकर्ता सबमिशन के लिए हम एरे के माध्यम से लूप करते हैं और एक .indexOf () यह देखने के लिए करते हैं कि स्ट्रिंग [] में कोई भी दिया गया शब्द सबमिशन में दिखाई देता है या नहीं।
  3. यदि ऐसा प्रतीत होता है, तो हम% $ # @% - शैली के पात्रों से प्रतिस्थापित करते हैं। यह उपयोगकर्ता सबमिशन को टोकन करके, पूरे उपयोगकर्ता सबमिशन को टोकन (फिर से) के रूप में पाकर, और पाए गए शब्द के प्रत्येक उदाहरण को प्रतिस्थापित करके किया जाता है।

इस समाधान में प्रतिभा हो सकती है, लेकिन मुझे संदेह है। और कुछ समय के लिए इस पर नज़र रखने के बाद मैं अपने तरीके से इसे पा नहीं सकता।

प्रश्न यह है कि ऐसा कौन सा समाधान है जो अच्छा प्रदर्शन देगा और उम्मीद है कि भविष्य के डेवलपर्स के लिए यथोचित रूप से समझदार बने रहूंगा क्योंकि मैंने कभी नहीं सुना है कि कुछ अस्पष्ट शब्द को फ़िल्टर करने में विफल रहने के लिए निकाल दिया जाए?


आप कहते हैं कि यह आपको गलत लगता है, हमें बताए बिना कि आप इसे गलत क्यों मानते हैं। फिर आप हमसे पूछे बिना, एक समाधान प्रस्तुत करते हैं, जिसमें वर्तमान समाधान पर्याप्त नहीं है। आप प्रति सेकंड कितने ग्रंथ प्राप्त करते हैं, उनमें से कितने आप प्रक्रिया कर सकते हैं?
उपयोगकर्ता अज्ञात

मुझे लगा कि समाधान गलत था, मुख्यतः क्योंकि मैं जिस कोडबेस में काम कर रहा हूं वह अपर्याप्त और मैला है। मेरे पूर्वाग्रह को देखते हुए, मुझे अपने अविश्वास पर भरोसा नहीं था। मुझे लगा कि दूसरों की राय फायदेमंद होगी। मेरे लिए अलार्म सेट करने वाली चीजें स्ट्रिंग थीं [] (क्या है, यह 1999 है?), बहुत बड़े स्ट्रिंग पर लूपिंग [] डेटा के बहुत छोटे सेट के बजाय उपयोगकर्ता सबमिट करता है, स्ट्रिंग के अंदर एक पाश को घोंसले में डालना [] पाश टोकन के साथ उपयोगकर्ता सबमिशन, और इसी तरह। अपेक्षित उपयोग अनिर्दिष्ट है, आदर्श रूप से उचित प्रदर्शन के साथ एक सुरुचिपूर्ण समाधान प्यारा होगा।
ब्लूशिगोल्डफ़िश

2
'उचित प्रदर्शन' का मतलब कुछ भी हो सकता है। यदि आपके पास कोई ठोस लक्ष्य नहीं है, तो आप यह नहीं जान सकते कि आप उस तक पहुँचे हैं या नहीं। यदि आप एक प्रक्रिया को गति देते हैं, जैसे कि यह 100 गुना तेज है - क्या यह एक लक्ष्य है? यदि उपयोगकर्ता 1ms या 1 / 10s प्रतीक्षा कर रहा है? उपयोगकर्ता को आपके काम से कोई लाभ नहीं होगा।
उपयोगकर्ता अज्ञात

जवाबों:


18

एक शब्द फिल्टर को बुद्धिमानी से करने का एकमात्र तरीका एक ध्वनि मेल प्रणाली का उपयोग करना है। मैंने कुछ साल पहले जावा में ट्वीन्स और किशोरावस्था के लिए एक बहुत लोकप्रिय बड़े पैमाने पर बहु-खिलाड़ी ऑनलाइन गेम के लिए एक बहुत प्रभावी अपवित्रता फ़िल्टर लिखा था।

यह एक अत्यधिक संशोधित डबल मेटाफोन एल्गोरिथ्म पर आधारित था जिसे डिफ़ॉल्ट के बजाय अधिक सटीक होने के लिए ट्वीक किया गया था जो कि संभव के रूप में कई चीजों से मेल खाने के लिए है। यह बहुत प्रभावी था क्योंकि यह गलत वर्तनी और ध्वन्यात्मक वर्तनी को वास्तविक शब्दों के समान ही उठाता था। मैंने मेटाफोन एल्गोरिथम के साथ-साथ स्पीक l33tऔर txtस्पीक को भी जोड़ा , जिससे यह ट्रिपल / क्वाड मेटाफोन एल्गोरिथ्म का अधिक हिस्सा बन गया।

इसमें एक प्री-प्रोसेसर दिखाया गया है जो अक्षरों को चलाने को संकुचित करता है और बच्चों को चीजों का पता लगाने जैसी चीजों का पता लगाता है जैसे w o r d sकि अक्षरों को समझदारी से एक साथ जोड़ना और चलने वाले डुप्लिकेट को खत्म करना wwoorrddss, यह केवल अंग्रेजी के लिए बहुत ही खास था।

यह काफी तेजी से 8 साल पहले एक कोर सीपीयू प्रणाली पर हजारों उपयोगकर्ताओं के दसियों के साथ किसी भी ध्यान देने योग्य विलंबता के बिना वास्तविक समय चैट सिस्टम स्ट्रीम में उपयोग करने के लिए पर्याप्त था।

हमारे पास शब्दों की एक सूची थी जो डेटाबेस में एक तालिका में मेटाफोन एन्कोडेड थे, और यह एक स्थिर मानचित्र में लोड किया गया था जो आश्चर्यजनक रूप से छोटा था और प्रतिबंधित शब्दों की सूची तक पहुंचने के लिए हमें कभी भी कुछ विशेष नहीं करना था, मैं इसे जोड़ने में सक्षम था लगभग मुफ्त में एक ही तकनीक का उपयोग करके वाक्यांश का पता लगाना।

निश्चित रूप से मेरे पास हजारों बच्चों के सभी चैट का एक रनिंग लॉग था जो वास्तविक समय में सिस्टम को तोड़ने की कोशिश कर रहा था, इसलिए मेरे पास काम करने के लिए डेटा का एक बहुत व्यापक सेट था। जिस तरह से मैंने लॉगिंग किया था, जब किसी ने फिल्टर को एक सकारात्मक के साथ ट्रिगर किया था, तो मैंने अगले कुछ चैट संदेशों को लॉग किया जो कि उनसे फिल्टर को ट्रिगर नहीं करता था , इस तरह अगर उन्होंने किसी विशेष शब्द या वाक्यांश के चारों ओर एक रास्ता खोजा, तो मैं कर सकता था। मेरे सिस्टम को अपनाएं और उसे पकड़ें। मैं कुछ हफ़्ते के बाद सुंदर बुलेट प्रूफ था।


3
यह समाधान सबसे अच्छा प्रतीत होता है। समस्या यह है (या इस बिंदु पर थी) कि मुझे इसे दोपहर में हल करना था। यदि पर्याप्त समय है, तो मैं या तो डबल मेटाफोन दृष्टिकोण ले लूंगा, या आपको इसे करने के लिए किराए पर लूंगा। :-)
ब्लूशिगोल्डफ़िश

इसलिए, मुझे लगता है कि आधे लोग अब खेल खेलना बंद कर देंगे: D
Davor 13dralo

2

यदि आप मिलान कुशलता से करना चाहते हैं, तो अहो कोरसिक एल्गोरिथ्म एक बहुत अच्छा विकल्प है (मुझे यकीन है कि आप जावा कार्यान्वयन को अस्थायी रूप से पा सकते हैं)।

बेशक आप किसी भी वर्तनी अनियमितताओं ('$' -> 's', '@' -> 'a', '<' -> 'k', आदि को बदलने के लिए सबमिशन को पूर्व-संसाधित करना चाहेंगे)


शायद ही मैं क्या देख रहा था, धन्यवाद! यहाँ एक जावा कार्यान्वयन है: hkn.eecs.berkeley.edu/ ~dyoo
रेमी मेइलिसन

0

एक स्थिर स्ट्रिंग [] में लोड करने के बजाय, हैश [] या कुछ अन्य प्रकार के बाइनरी ट्री (यदि आप खोज में सुधार करना चाहते थे) का उपयोग करके स्ट्रिंग को हैश में अपनी कुंजी बनाएं। अपने स्ट्रिंग को रिक्त स्थान से विभाजित करें और विराम चिह्न हटा दें। फिर आप अपने स्ट्रिंग स्प्लिट में प्रत्येक शब्द के लिए हाशप को क्वेरी कर सकते हैं; यदि हैशमाप गैर अशक्त के साथ वापस आता है तो आप जानते हैं कि आपके पास एक बुरा शब्द है।

यहां जो चीज विफल हो जाती है वह है क्लैबटिक समस्या जहां कोई व्यक्ति बुरे शब्द के आसपास यादृच्छिक अक्षर जोड़ता है। bhassda


मुझे लगता है कि आखिरी कैविएट इस समाधान को बहुत बेकार बना देता है - इसे कुछ भी नहीं बल्कि पूरे शब्द के मैचों तक विस्तारित करने का कोई तरीका नहीं है।

यह एक उचित बयान है; लेकिन हर संभव चीज़ को पकड़ना कठिन हो जाता है, जो मानव मन के साथ अपवित्रता को दूर करने के लिए आ सकता है। आप हमेशा सभी विकल्पों को संयोजित करने के लिए OR बयानों के साथ एक विशाल नियमित अभिव्यक्ति बना सकते हैं और फिर इनपुट के खिलाफ रेगेक्स से मिलान कर सकते हैं। या आप डेटाबेस से "खराब शब्द क्षेत्र" के साथ डेटाबेस से इनपुट के विरुद्ध एक RLIKE के साथ चयन कर सकते हैं। रिटर्न बुरा शब्द इंगित करता है और बुरा शब्द भी लौटाएगा।

@ किसी भी शब्द या वाक्यांश के बारे में बस पकड़ना मुश्किल नहीं है, जैसे मेरे प्रश्न के बारे में ध्वन्यात्मक मिलान के साथ वाक्यांश। निरपेक्ष मिलान कभी भी काम या पैमाना नहीं होगा, लेकिन ध्वन्यात्मक मिलान एक बार जब आप संभवतः प्राप्त कर सकते हैं तो 100% के करीब काम करता है।

-1

किसी भी तरह से एक ध्वनि प्रणाली का उपयोग एकमात्र समाधान नहीं है, लेकिन यह सबसे सरल हो सकता है क्योंकि बहुत सारे खुले स्रोत पुस्तकालय हैं जो उस तरह का काम करते हैं।

कठिन हिस्सा हमेशा किसी भी एल्गोरिथ्म का मेल खाने वाला हिस्सा होता है और ऐसा लगता है कि आपका मैच काफी धीमा और भोला है। आप यह नहीं मान सकते हैं कि अनुक्रमणिका किसी सहायक जाँच के कुछ प्रकार के बिना सही ढंग से मेल खाएगी।

इसके अलावा, आप पूरे स्ट्रिंग N समय पर लूपिंग समाप्त करेंगे, जहाँ N आपके ब्लैकलिस्ट पर शब्दों की संख्या है। सेट या हाशपैप का उपयोग करने के सुझाव निश्चित रूप से कुछ हद तक चीजों को बेहतर बनाने वाले हैं।

ज्यादातर मामलों में, एक रैखिक राज्य आधारित एल्गोरिथ्म सबसे अच्छा और सबसे तेज़ है। मैंने क्लीन स्पीक का हल लिखा है और यह इस प्रकार के एल्गोरिथ्म का उपयोग प्री-प्रोसेस फॉनिक मैचिंग सिस्टम के साथ करता है। यह एकमात्र ऐसा समाधान था जो अपवित्रता (यदि फू अपवित्रता है, एम्बेडिंग फॉक्सुकेर है) के जटिल होने पर जटिल नहीं हुआ और प्रदर्शन के उच्च स्तर को बनाए रखने में सक्षम था। यह नए कोडेक्स के कार्यान्वयन के बिना अन्य भाषाओं के लिए अच्छी तरह से तराजू है।

अंत में, किसी भी रूप का पूर्व-प्रसंस्करण आमतौर पर बचने के लिए कुछ है। ज्यादातर मामलों में आप एक ही कार्य को रेखीय अंदाज में कर सकते हैं क्योंकि आप प्रत्येक अक्षर को स्ट्रिंग में संभालते हैं।

बेशक, मैं लंबे समय में अन्य समाधानों को देखने का सुझाव दूंगा क्योंकि अधिकांश अनुप्रयोगों में उपयोगकर्ता-जनित सामग्री को संभालना केवल अपवित्र फ़िल्टरिंग की तुलना में अधिक जटिल है। अक्सर आप व्यक्तिगत जानकारी जैसे ईमेल और सामाजिक सुरक्षा नंबर और कभी-कभी URL जैसी चीजों को भी फ़िल्टर करना चाहते हैं। साथ ही, हमने पाया है कि अधिकांश अनुप्रयोगों को कुछ प्रकार की मॉडरेशन प्रणाली और सामग्री खोज की आवश्यकता होती है। इनसे जटिलता काफी बढ़ जाती है।


-2

आप इस तरह से एक मामले में क्या करना चाहते हैं यह निर्धारित करता है कि शब्दों की दो सूचियों में से कौन सी छोटी है। मान लें कि आपकी "वर्बोटन" सूची में 2000 शब्द हैं और अधिकतम उपयोगकर्ता प्रस्तुत 500 शब्द हैं। उस स्थिति में, आप उपयोगकर्ता द्वारा प्रस्तुत किए गए शब्दों की सूची के माध्यम से पुनरावृत्ति करेंगे और उन्हें निषिद्ध शब्दों और इसके विपरीत की सूची में एक-एक करके देखेंगे।

अन्य परिवर्तन जो मैं करूंगा वह यह है कि आप वर्जित शब्दों की सूची को एक स्ट्रिंग [] में नहीं रखते हैं - यदि आप उस सरणी में खोज करते हैं जिसे आपने उपयोगकर्ता सबमिशन में प्रति शब्द ओ (एन) खोज लिया है। यह बहुत बुरा है। मैं उस डेटा संरचना को डालने की कोशिश करूंगा, जिसे आप किसी प्रकार के साहचर्य कंटेनर या पेड़ की संरचना में देख रहे हैं, जिसमें बेहतर लुकअप प्रदर्शन (एन के बजाय एन लॉग) है। यहां चुनौती यह होगी कि यदि आप उपयोगकर्ता को इस कंटेनर में डालते हैं, तो आपको शब्द स्थिति पर नज़र रखनी होगी ताकि आप इनपुट को फिर से संगठित कर सकें या खोज हिट होने पर इनपुट स्ट्रिंग को अपडेट कर सकें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.