2010-09-24 12 views
6

मेरे पास दो तार हैं जिनमें रिक्त स्थान से अलग अक्षरों और संख्याएं हैं। पूर्व "elza7ma wa2fa fel matab" और "2ana ba7eb el za7ma 2awy 2awy"सी # मिलान करने वाले शब्दों के लिए दो तारों की तुलना करें

यह दो स्ट्रिंग की तुलना करने के लिए सबसे तेज़ तरीका क्या है यह पता लगाने के लिए कि उनके पास एक शब्द आम है या नहीं?

मैंने string.split का उपयोग करके उनमें से एक को विभाजित करने का प्रयास किया और शब्दों की पूरी सरणी पर string.compare का उपयोग किया। लेकिन यह बहुत धीमा है क्योंकि मैं बहुत सारे तारों की तुलना करूँगा।

+0

ऐसा लगता है कि indexOf तेजी से काम करेगा, फिर regex, हालांकि यह नहीं पता कि यह तेजी से है तो string.compare :)। आप – Danil

+1

कोशिश कर सकते हैं क्या आप वास्तव में * सबसे तेज़ * चाहते हैं? आप उस समस्या पर सचमुच * साल * के लिए काम कर सकते हैं। मुझे संदेह है कि आप * तेजी से पर्याप्त * चाहते हैं, इस मामले में, आपने समस्या को हल करने के लिए पर्याप्त जानकारी नहीं दी है। * आपका हार्डवेयर क्या है, आपका समय बजट क्या है, और आम तौर पर आकार की समस्या क्या है? * –

+3

इसके अलावा, "बहुत सारे तार" क्या हैं? नीचे दी गई आपकी टिप्पणियां इंगित करती हैं कि "बहुत" सैकड़ों है। मैं सैकड़ों को * अविश्वसनीय रूप से तारों की संख्या * पर विचार करता हूं। क्या यह सही है? मैं लाखों या अरबों तारों के "बहुत" पर विचार करता हूं - जैसा कि, बिंग बहुत सारे तारों को अनुक्रमणित करता है। समस्या के आकार का अच्छा विचार किए बिना आपको एक अच्छा जवाब देना मुश्किल है। –

उत्तर

14

एक LINQ समाधान

"elza7ma wa2fa fel matab".Split() 
         .Intersect("2ana ba7eb el za7ma 2awy 2awy".Split()) 
         .Any(); 

// as a string extension method 
public static class StringExtensions 
{ 
    public static bool OneWordMatches(this string theString, string otherString) 
    { 
     return theString.Split().Intersect(otherString.Split()).Any(); 
    } 
} 

// returns true 
"elza7ma wa2fa fel matab 2ana".OneWordMatches("2ana ba7eb el za7ma 2awy 2awy"); 
+0

'स्प्लिट' का कोई अधिभार कोई एकल 'char' नहीं लेता है। शायद 'RemoveEmptyEntries' – JaredPar

+0

निर्दिष्ट करने के लिए सबसे अच्छा आप किसी भी पैरामीटर के बिना' स्प्लिट() 'का उपयोग कर सकते हैं। इस मामले में यह स्पेस, टैब और नई लाइनों को विभाजक के रूप में उपयोग करेगा। – Oliver

+0

क्या यह वास्तव में तेज़ है, या इंटरसेक्ट() भी दोनों सरणी के माध्यम से loops करता है? – Sjoerd

5

मुझे लगता है कि सबसे आसान तरीका है शब्दों में तार टूटने और HashSet<string> की तरह एक सेट संरचना का उपयोग डुप्लिकेट की जांच करने के लिए है। उदाहरण के लिए

public bool HasMatchingWord(string left, string right) { 
    var hashSet = new HashSet<string>(
    left.Split(" ", StringSplitOptions.RemoveEmptyEntries)); 
    return right 
    .Split(" ", StringSplitOptions.RemoveEmptyEntries) 
    .Any(x => hashSet.Contains(x)); 
} 
+1

टक्कर को संभालने के लिए समानता जांच भी जोड़ना चाह सकता है (यदि कोई है तो)। –

+0

क्या कोई यह सुनिश्चित करता है कि यह सर्वोत्तम तरीका प्रदर्शन के अनुसार है? – Marwan

1

आप दो तारों को शब्द से विभाजित कर सकते हैं और दो हैशटबेल/शब्दकोश बना सकते हैं। फिर दोनों के माध्यम से जाएं और एक तीसरे शब्दकोश (Dictionary<string, int>) में एक int बढ़ाने के लिए कुंजी जोड़ें। यदि तीसरे शब्दकोश में किसी भी कुंजी की एक से अधिक की गिनती है, तो वह शब्द मूल तार दोनों में है।

मुझे लगता है कि इस समस्या को हल करने के लिए कोई भी एल्गोरिदम 'धीमा' होगा - खासकर बड़े इनपुट स्ट्रिंग/कई शब्दों के लिए।

+0

सभी शब्दों को एक ही हैशसेट में जोड़ना और जोड़ें() का वापसी मान जांचना आसान है। – Sjoerd

+0

मैं मूल प्रश्न दोबारा पढ़ता हूं - हाँ यह बहुत आसान होगा। वह सिर्फ यह पूछ रहा है कि क्या कोई शब्द हैं जो दोनों तारों में दर्शाए जाते हैं - न कि कितने मौके। – mbanzon

0

मैं शायद प्रारंभिक प्रदर्शन हिट लेता हूं और स्ट्रिंग को विभाजित करता हूं और फिर वर्णानुक्रम और शब्द की लंबाई के अनुसार क्रमबद्ध करता हूं। यदि आपको पता लगाना है कि एक शब्द मेल खाता है, तो जैसे ही आप पाते हैं तो ब्रेक करें। एक बार जब आपके पास स्प्लिट स्ट्रिंग सरणी वर्णानुक्रम और लंबाई के अनुसार आदेश दिया जाता है, तो यह तुलना करने की संख्या को सीमित करता है जो आपको करना होगा।

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