यह वही नहीं है जो आप चाहते हैं लेकिन कहें कि मेरे पास अधिक समय है। निम्नलिखित regex से तेजी से काम करना चाहिए।
static bool IsAlphaAndNumeric(string str) {
bool hasDigits = false;
bool hasLetters=false;
foreach (char c in str) {
bool isDigit = char.IsDigit(c);
bool isLetter = char.IsLetter(c);
if (!(isDigit | isLetter))
return false;
hasDigits |= isDigit;
hasLetters |= isLetter;
}
return hasDigits && hasLetters;
}
इसकी तेज़ी से इसकी जांच क्यों करें। परीक्षण स्ट्रिंग जेनरेटर निम्नलिखित है। यह 1/3 सेट पूरी तरह से सही स्ट्रिंग और 2/3 विज्ञापन गलत उत्पन्न करता है। 2/3 1/2 में सभी अल्फा और अन्य आधा सभी अंक हैं।
static IEnumerable<string> GenerateTest(int minChars, int maxChars, int setSize) {
string letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
string numbers = "";
Random rnd = new Random();
int maxStrLength = maxChars-minChars;
float probablityOfLetter = 0.0f;
float probablityInc = 1.0f/setSize;
for (int i = 0; i < setSize; i++) {
probablityOfLetter = probablityOfLetter + probablityInc;
int length = minChars + rnd.Next() % maxStrLength;
char[] str = new char[length];
for (int w = 0; w < length; w++) {
if (probablityOfLetter < rnd.NextDouble())
str[w] = letters[rnd.Next() % letters.Length];
else
str[w] = numbers[rnd.Next() % numbers.Length];
}
yield return new string(str);
}
}
डारिन दो समाधान निम्नलिखित है। एक संकलित है और दूसरा गैर संकलित संस्करण है।
class DarinDimitrovSolution
{
const string regExpression = @"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$";
private static readonly Regex _regex = new Regex(
regExpression, RegexOptions.Compiled);
public static bool IsAlphaAndNumeric_1(string s) {
return _regex.IsMatch(s);
}
public static bool IsAlphaAndNumeric_0(string s) {
return Regex.IsMatch(s, regExpression);
}
पीछा कर रहा है परीक्षण पाश
static void Main(string[] args) {
int minChars = 3;
int maxChars = 13;
int testSetSize = 5000;
DateTime start = DateTime.Now;
foreach (string testStr in
GenerateTest(minChars, maxChars, testSetSize)) {
IsAlphaNumeric(testStr);
}
Console.WriteLine("My solution : {0}", (DateTime.Now - start).ToString());
start = DateTime.Now;
foreach (string testStr in
GenerateTest(minChars, maxChars, testSetSize)) {
DarinDimitrovSolution.IsAlphaAndNumeric_0(testStr);
}
Console.WriteLine("DarinDimitrov 1 : {0}", (DateTime.Now - start).ToString());
start = DateTime.Now;
foreach (string testStr in
GenerateTest(minChars, maxChars, testSetSize)) {
DarinDimitrovSolution.IsAlphaAndNumeric_1(testStr);
}
Console.WriteLine("DarinDimitrov(compiled) 2 : {0}", (DateTime.Now - start).ToString());
Console.ReadKey();
}
के बाद का मुख्य है परिणाम
My solution : 00:00:00.0170017 (Gold)
DarinDimitrov 1 : 00:00:00.0320032 (Silver medal)
DarinDimitrov(compiled) 2 : 00:00:00.0440044 (Gold)
तो सबसे पहले समाधान सबसे अच्छा था। कुछ और रिलीज़ मोड में परिणाम और कल्पना
int minChars = 20;
int maxChars = 50;
int testSetSize = 100000;
My solution : 00:00:00.4060406
DarinDimitrov 1 : 00:00:00.7400740
DarinDimitrov(compiled) 2 : 00:00:00.3410341 (now that very fast)
मैं RegexOptions.IgnoreCase ध्वज के साथ फिर से जाँच की निम्नलिखित। ऊपर
My solution : 00:00:00.4290429 (almost same as before)
DarinDimitrov 1 : 00:00:00.9700970 (it have slowed down)
DarinDimitrov(compiled) 2 : 00:00:00.8440844 (this as well still fast but look at .3 in last result)
बाद gnarf मेरी algo यदि स्ट्रिंग केवल और अंक पत्र से मिलकर बनता है तो मैं इसे बदल उसकी जांच करने गया था के साथ एक समस्या थी कि उल्लेख और अब यह है कि स्ट्रिंग शो की जाँच के रूप में ही परम के बाकी कम से कम एक चार है और एक अंक।
static bool IsAlphaNumeric(string str) {
bool hasDigits = false;
bool hasLetters = false;
foreach (char c in str) {
hasDigits |= char.IsDigit(c);
hasLetters |= char.IsLetter(c);
if (hasDigits && hasLetters)
return true;
}
return false;
}
परिणाम
My solution : 00:00:00.3900390 (Goody Gold Medal)
DarinDimitrov 1 : 00:00:00.9740974 (Bronze Medal)
DarinDimitrov(compiled) 2 : 00:00:00.8230823 (Silver)
मेरा एक बड़ा पहलू से तेज है।
यदि आप केवल इनमें से कम से कम 1 सत्यापित करना चाहते हैं, तो अनावश्यक रूप से लंबी स्ट्रिंग से मेल खाने के लिए '+' ऑपरेटर का उपयोग न करें। – kennytm
मुझे लगता है कि मूल संस्करण अधिकतर उत्तर से अधिक सुरुचिपूर्ण और पठनीय है। – Kobi
मुझे लगता है कि इस विधि को ** HasAlphaAndNumeric ** कहा जाना चाहिए। आप केवल यह जांच रहे हैं कि इसमें * प्रत्येक में से एक है; बाकी के पात्र कुछ भी हो सकते हैं, या कुछ भी नहीं। उदाहरण के लिए, 'ए 1' और'! @ # 1%^और ए() _ 'दोनों पास - क्या आप इसका इरादा रखते हैं? –