2013-01-25 15 views
5

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

a) 'a'-'z' chars 
b) '*' chars which can be matched by 0 or more letters 
c) '?' which just matches to a character - any letter basically 

तो कॉल

की तरह कुछ हो सकता है:

givenPattern एक स्ट्रिंग है शामिल है:

तो तुम जो निम्न करता

boolean isPattern(String givenPattern, String stringToMatch) 

समारोह का निर्माण करने के लिए है

isPattern("abc", "abcd") - झूठी वापसी करता है क्योंकि यह डी ओ इ एस आकार से मिलान नहीं ('प' अतिरिक्त है)

isPattern("a*bc", "aksakwjahwhajahbcdbc") है, जो सच है के रूप में हम एक 'एक' शुरू में, कई पात्रों के बाद और फिर इसे "ई.पू."

isPattern("a?bc", "adbc") रिटर्न सच के साथ समाप्त होता है जैसा कि पैटर्न के प्रत्येक चरित्र दिए गए स्ट्रिंग में मेल खाता है।

साक्षात्कार के दौरान, समय छोटा होने पर, मुझे लगा कि कोई पैटर्न के माध्यम से चल सकता है, देखें कि कोई चरित्र एक पत्र है, एक * या एक? और उसके बाद क्रमशः दिए गए स्ट्रिंग में वर्णों से मेल खाते हैं। लेकिन यह फॉर-लूप का एक जटिल सेट बन गया और हमने 45 मिनट के भीतर एक निष्कर्ष निकालने का प्रबंधन नहीं किया।

क्या कोई मुझे बता सकता है कि वे इस समस्या को जल्दी और कुशलता से कैसे हल करेंगे?

बहुत धन्यवाद!

+2

सबसे आसान तरीका है जावा नियमित अभिव्यक्ति के लिए इस पद्धति वाक्य रचना का अनुवाद के लिए एक विधि लिखने के लिए होगा: http://docs.oracle.com/javase/tutorial/आवश्यक/regex/ – hsan

+1

क्लासिक गतिशील प्रोग्रामिंग प्रश्न। – Srinivas

+0

ठीक है। वह मेरा सवाल भी था। क्या आपको रेगेक्स का उपयोग करने की अनुमति है? यदि हां, तो यह @assylias द्वारा कोड में चित्रित अपेक्षाकृत आसान होना चाहिए। – aa8y

उत्तर

3
boolean isPattern(String givenPattern, String stringToMatch) { 
    if (givenPattern.empty) 
     return stringToMatch.isEmpty(); 
    char patternCh = givenPatter.charAt(0); 
    boolean atEnd = stringToMatch.isEmpty(); 
    if (patternCh == '*') { 
     return isPattenn(givenPattern.substring(1), stringToMatch) 
      || (!atEnd && isPattern(givenPattern, stringToMatch.substring(1))); 
    } else if (patternCh == '?') { 
     return !atEnd && isPattern(givenPattern.substring(1), 
      stringToMatch.substring(1)); 
    } 
    return !atEnd && patternCh == stringToMatch.charAt(0) 
      && isPattern(givenPattern.substring(1), stringToNatch.subtring(1); 
} 

(Recursion को समझने के लिए सबसे आसान है।)

+0

मुझे लगता है कि आपकी पहली वापसी में विकृत है, आप केवल एक पैरामीटर पास कर रहे हैं और यह एक बुलियन है। इसके अलावा आप अर्धविराम गायब हैं। –

+0

मुझे लगता है कि आप वापस लौटना चाहते हैं! AtEnd && isPattern (दिया गया पैटर्न, stringToMatch.substring (1)); ' –

+0

@JamesMcMahon सही। इसे ठीक किया –

6

मान लें आप regexes उपयोग करने के लिए अनुमति दी जाती है, तो आप की तरह कुछ लिख सकता:

static boolean isPattern(String givenPattern, String stringToMatch) { 
    String regex = "^" + givenPattern.replace("*", ".*").replace("?", ".") + "$"; 

    return Pattern.compile(regex).matcher(stringToMatch).matches(); 
} 

"^" स्ट्रिंग
"$" की शुरुआत है स्ट्रिंग के अंत
. "किसी भी चरित्र के लिए है ", ठीक उसी बार
.*" किसी भी चरित्र ", 0 या अधिक बार

नोट: यदि आपको प्रतिबंधित करना चाहते हैंऔर ? केवल अक्षरों के लिए, आप . के बजाय [a-zA-Z] का उपयोग कर सकते हैं।

+0

मन को रेगेक्स की संरचना के आसपास कुछ अतिरिक्त जानकारी डालना? मुझे लगता है कि यह जवाब में सुधार होगा। –

+0

@JamesMcMahon मैंने ऐसा किया है। – assylias

+2

क्या होगा यदि दिए गए स्ट्रिंग में रेगेक्स वाइल्डकार्ड हैं लेकिन इन्हें व्याख्या नहीं किया जाना चाहिए? इसका उपयोग करने से पहले आपको सभी ज्ञात रेगेक्स वाइल्डकार्ड से बचना होगा। –

संबंधित मुद्दे