这不是您想要的,但可以说我有更多时间。以下应该比正则表达式更快。
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 = "0123456789";
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);
}
}
以下是darin 两个解决方案。一个已经编译,另一个是未编译版本。
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 提到我的算法存在问题后,它正在检查字符串是否仅由字母和数字组成,因此我对其进行了更改,现在它检查字符串显示是否至少有一个字符和一个数字。
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)
我的速度很快。