दिलचस्प पोस्ट
हाइफ़न के बाद लाइन-ब्रेक नहीं Android में कॉलबैक क्या है? MySQL किसी फ़ील्ड में कुछ पाठ को खोज और प्रतिस्थापित करता है लिनक्स में एक फाइल को सिमलिंक कैसे करें? जावा को सी # कोड में कनवर्ट करने के लिए टूल XCode "DTAssetProviderService प्रारंभ नहीं कर सका .." त्रुटि, यह कैसे ठीक करें? एमओवी और एलईए के बीच अंतर क्या है? मिश्रित अल्फा / संख्यात्मक सरणी सॉर्ट करें जब एक 'धुंधला' घटना होती है, तो मैं यह कैसे पता लगा सकता हूँ कि कौन सा तत्व फोकस * * पर गया? एब्स्ट्रक्शन वी.एस. जानकारी छिपाना वी.एस. क्यों Spring's ApplicationContext.getBean खराब माना जाता है? जब ओरिएंटेशन परिवर्तन होता है तो एप्लिकेशन को फिर से लोड न करें एंड्रॉइड: मैं ग्राफ़ के लिए एचकर्ट एंजिन लाइब्रेरी का उपयोग कर रहा हूं, लेकिन एंड्रॉइड एक्सएमएल के साथ ऐंचैर्टगिन के ग्राफ दृश्य को एकीकृत करने में सक्षम नहीं है? प्रेरणा भावना अर्थ क्रियापदों जावा में वाष्पशील बनाम स्थिर

यह निर्धारित करने के लिए कि क्या कोई संख्या regex के साथ एक प्रमुख है?

मुझे RosettaCode पर जावा के लिए निम्नलिखित कोड का उदाहरण मिला:

public static boolean prime(int n) { return !new String(new char[n]).matches(".?|(..+?)\\1+"); } 
  • मैं विशेष रूप से जावा को नहीं जानता, लेकिन इस स्निपेट के सभी पहलुओं को समझता हूं केवल खुद को छोड़कर regex
  • मेरे पास रेगेक्स के बुनियादी-उन्नत ज्ञान के मूलभूत रूप हैं, क्योंकि आपको इसे अंतर्निहित PHP फ़ंक्शन में मिलता है

कैसे करता है .?|(..+?)\\1+ प्रधान संख्याओं को .?|(..+?)\\1+ ?

वेब के समाधान से एकत्रित समाधान "यह निर्धारित करने के लिए कि क्या कोई संख्या regex के साथ एक प्रमुख है?"

आपने कहा है कि आप इस हिस्से को समझते हैं, लेकिन सिर्फ जोर देने के लिए, उत्पन्न स्ट्रिंग की आपूर्ति की गई संख्या के बराबर लंबाई है इसलिए स्ट्रिंग में तीन वर्ण हैं और यदि केवल n == 3

 .? 

रेगेक्स का पहला भाग कहते हैं, "कोई भी चरित्र, शून्य या एक बार" तो मूल रूप से, शून्य या एक अक्षर है – या, मैं जो ऊपर वर्णित है, n == 0 || n == 1 n == 0 || n == 1 यदि हमारे पास मैच है, तो उसके बदले में वापसी करें यह इस तथ्य से मेल खाती है कि शून्य और कोई प्रधान नहीं है

 (..+?)\\1+ 

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

समूह 1 चरित्र को कब्जा करता है, फिर 1 या अधिक किसी भी वर्ण का। (+ चरित्र का मतलब है एक या अधिक, लेकिन केवल पिछले वर्ण या समूह का। तो यह "दो या चार या छह आदि वर्ण" नहीं है, बल्कि "दो या तीन इत्यादि" + + जैसा है +, लेकिन यह संभव के रूप में कुछ अक्षर के रूप में मिलान करने की कोशिश करता है। सामान्य रूप से पूरे स्ट्रिंग को झुकने की कोशिश करता है, यदि यह हो सकता है, जो इस मामले में खराब है क्योंकि यह बैक्रेफरेंस भाग को काम से रोकता है।)

अगला भाग बैक्रेफरेंस है: उस वही अक्षर का सेट (दो या अधिक), फिर से दिख रहा है। ने कहा कि बैक्रेफरेंस एक या अधिक बार दिखाई देता है।

इसलिए। कब्जा कर लिया गया समूह पात्रों की एक प्राकृतिक संख्या (2 आगे) से कब्जा कर लिया है समूह ने कहा कि तब कुछ प्राकृतिक संख्या दिखाई देती है (2 से आगे भी)। यदि कोई मैच है, तो इसका अर्थ है कि दो से अधिक संख्याओं के उत्पाद को खोजना संभव है जो 2 से अधिक या उसके बराबर है जो एन-लम्बाई स्ट्रिंग से मेल खाता है … अर्थ है कि आपके पास समग्र एन है तो फिर, सफल मैच का नकारा वापस लौटाएं: n प्राइम नहीं है

अगर कोई मैच नहीं मिला, तो आप दो प्राकृतिक संख्याओं के अपने उत्पाद के साथ नहीं आ सकते हैं जो कि 2 से अधिक या उसके बराबर है … और आपके पास एक गैर-मैच और एक प्रधान दोनों है, इसलिए फिर से अस्वीकृति की वापसी मैच परिणाम का

क्या आप इसे अब देख रहे हैं? यह अविश्वसनीय रूप से मुश्किल है (और कम्प्यूटेशनलली महंगे!), लेकिन एक बार जब आप इसे प्राप्त करते हैं, तब भी यह एक तरह से सरल होता है। 🙂

अगर आपके पास और प्रश्न हैं, तो मैं विस्तृत कर सकता हूं, जैसे रीजक्स पार्सिंग वास्तव में कैसे काम करता है। लेकिन मैं इस उत्तर को अब तक सरल रखने की कोशिश कर रहा हूं (या जितना आसान हो सकता है)।

मैं प्राइमलिटी टेस्टिंग के बाहर रेगेक्स भाग समझाऊंगा: निम्नलिखित रेगेक्स, String s जो String t को दोहराते हुए देखते हैं, उसे ढूंढता t

  System.out.println( "MamamiaMamamiaMamamia".replaceAll("^(.*)\\1+$", "$1") ); // prints "Mamamia" 

जिस तरह से यह काम करता है वह है कि regex को (.*) \1 (.*) में कैप्चर करता है (.*) , और फिर देखता है कि इसके बाद का \1+ ^ और $ का उपयोग सुनिश्चित करता है कि एक मैच पूरे स्ट्रिंग का होना चाहिए।

तो, एक तरह से, हमें String s दिया जाता है, जो String t का "मल्टीपल" होता String t , और regex ऐसे t पाएंगे (सबसे लंबे समय तक संभव है, क्योंकि \1 लालची है)।

एक बार जब आप समझते हैं कि यह रीजेक्स क्यों काम करता है, तो (अब ओपी के रेजेक्स में पहले वैकल्पिक की अनदेखी कर), समझाएं कि प्राइमलिटी परीक्षण के लिए इसका उपयोग कैसे किया जाता है

  • n मूलभूतता का परीक्षण करने के लिए, पहले String की लम्बाई n बनाएं (एक ही char से भरा)
  • Regex कुछ लंबाई का एक String ( k ) को \1 में लेता है, और शेष String लिए \1+ से मिलान करने का प्रयास करता है
    • यदि कोई मैच है, तो n k का एक उचित k , और इसलिए n प्राइम नहीं है।
    • अगर कोई मेल नहीं है, तो ऐसा कोई भी मौजूद नहीं है जो n विभाजित करता है, और n इसलिए एक प्रमुख है

कैसे करता है .?|(..+?)\1+ प्रधान संख्याओं को .?|(..+?)\1+ ?

दरअसल, यह नहीं है! यह String मेल खाता है जिसका लम्बाई प्रधानमंत्री नहीं है!

  • .? : प्रत्यावर्तन का पहला भाग String की लंबाई 0 या 1 (परिभाषा के अनुसार प्रधान नहीं है)
  • (..+?)\1+ : प्रत्यावर्तन का दूसरा भाग, ऊपर वर्णित रीगेक्स की एक भिन्नता, लंबाई के String से मेल खाता है जो कि String की लंबाई " k >= 2 (अर्थात n एक है समग्र, नहीं एक प्रमुख)।
    • ध्यान दें कि अनिच्छुक संशोधक ? वास्तव में शुद्धता के लिए आवश्यक नहीं है, लेकिन यह छोटी k पहली कोशिश करके प्रक्रिया को तेज करने में मदद कर सकता है

ध्यान दें ! return वक्तव्य में boolean पूरक ऑपरेटर: यह matches नकार देता है यह तब होता है जब regex मेल नहीं खाता है, n प्रधान है! यह एक डबल-नकारात्मक तर्क है, इसलिए कोई आश्चर्य नहीं कि यह भ्रामक है !!


सरलीकरण

इसे और अधिक पठनीय बनाने के लिए कोड का एक सरल पुन: लिखना यहां दिया गया है:

 public static boolean isPrime(int n) { String lengthN = new String(new char[n]); boolean isNotPrimeN = lengthN.matches(".?|(..+?)\\1+"); return !isNotPrimeN; } 

उपरोक्त अनिवार्यतः मूल जावा कोड के समान है, लेकिन तर्क को आसान समझने के लिए स्थानीय चर के असाइनमेंट के साथ कई बयानों में अलग हो गया है।

हम रेगएक्स को सरलीकृत पुनरावृत्ति का उपयोग करके भी सरल कर सकते हैं, निम्नानुसार:

 boolean isNotPrimeN = lengthN.matches(".{0,1}|(.{2,})\\1+"); 

फिर, एक String की लम्बाई दी, जो एक ही char से भरी होती है,

  • .{0,1} जांचता है कि n = 0,1 , नहीं प्रधानमंत्री
  • (.{2,})\1+ चेक अगर n एक के बराबर है k >= 2 , नहीं प्रधानमंत्री

अनिच्छुक संशोधक के अपवाद के साथ ? पर \1 (स्पष्टता के लिए छोड़े गए), उपरोक्त regex मूल के समान है।


अधिक मज़ा regex

निम्नलिखित regex समान तकनीक का उपयोग करता है; यह शैक्षिक होना चाहिए:

 System.out.println( "OhMyGod=MyMyMyOhGodOhGodOhGod" .replaceAll("^(.+)(.+)(.+)=(\\1|\\2|\\3)+$", "$1! $2! $3!") ); // prints "Oh! My! God!" 

यह भी देखें

  • रेगुलर एक्सप्रेशंस: लोभी कौन है

अच्छा रेगेक्स चाल (हालांकि बहुत अक्षम) … 🙂

रेगेक्स गैर-प्राइम को निम्नानुसार परिभाषित करता है:

एन प्रधान नहीं है अगर और केवल अगर एन <= 1 या एन कुछ के द्वारा विभाज्य है> 1

रेगेक्स इंजन को एन के सरल डिजिटल प्रस्तुति को पारित करने के बजाय, यह लम्बाई एन के एक अनुक्रम से खिलाया जाता है, जिसमें दोहराए जाने वाले चरित्र का निर्माण होता है। N = 0 या N = 1 के लिए विच्छेदन की जांच का पहला भाग, और दूसरा, बैकरेरिएंट्स का उपयोग करके एक विभाजक के> 1 के लिए दिखता है। यह regex इंजन को कुछ गैर खाली उप-अनुक्रम को खोजने के लिए मजबूर करता है जिसे अनुक्रम बनाने के लिए कम-से-कम दो बार दोहराया जा सकता है। यदि इस तरह के बदलाव की मौजूदगी है, तो इसका मतलब है कि इसकी लंबाई एन को विभाजित करती है, इसलिए एन प्रधान नहीं है

 /^1?$|^(11+?)\1+$/ 

आधार 1 (1 = 1, 2 = 11, 3 = 111, …) में रूपांतरण के बाद नंबर पर लागू करें। गैर-प्राइम इस से मेल खाएंगे। यदि यह मेल नहीं खाता है, तो यह प्रमुख है।

स्पष्टीकरण यहाँ ।