您当前的解决方案是O(MN),创建您的字符串值的查找并进行检查。
public static bool ContainsOnlyChars(string strValue,params char[] charValues)
{
if (string.IsNullOrEmpty(strValue))
throw new ArgumentNullException("String cannot be null or empty.");
var chrLookup = charValues.ToLookup(c => c);
for (int i = 0; i < strValue.Length; i++)
{
if (!chrLookup.Contains(strValue[i]))
{
return false;
}
}
return true;
}
,
相互检查两个列表是O(n * m)
的任务,其中n和m是列表的大小。但是,如果两个人都足够长,则可以使用HashSets
在其中找到另一个项目。
在您的情况下,您可以使用时间O(n)
从原始字符串创建字典,然后使用时间O(m)
检查该字典中是否存在其他每个项目,使其成为O(n + m)
算法
public static bool ContainsOnlyChars(string strValue,params char[] charValues)
{
if (string.IsNullOrEmpty(strValue))
throw new ArgumentNullException("String cannot be null or empty.");
// The O(n) part
var dic = new Dictionary<char,bool>();
foreach (var ch in strValue)
if (!dic.ContainsKey(ch))
dic.Add(ch,1);
// The O(m) part
foreach (var ch in charValues)
if(!dic.ContainsKey(ch))
return false;
return true;
}
免责声明:我已经在浏览器中编写了代码。
,
要考虑的替代方法是:
public static bool ContainsOnlyChars(string strValue,params char[] charValues)
{
if (string.IsNullOrEmpty(strValue))
throw new ArgumentNullException("String cannot be null or empty.");
return !strValue.Except(charValues).Any();
}
如果false
中的任何字符不在strValue
中,则代码基本上返回charValues
。
,
解决方案
您可以简单地解析字符串的字符,并检查所提供的字符是否包含它们。
您将获得最佳的速度和内存性能。
使用扩展方法
static public class StringHelper
{
static public bool ContainsOnlyChars(this string strValue,params char[] charValues)
{
if ( string.IsNullOrEmpty(strValue) )
throw new ArgumentNullException("String cannot be null or empty.");
if ( charValues == null )
throw new ArgumentNullException("Chars cannot be null.");
for ( int index = 0; index < strValue.Length; index++ )
if ( !charValues.Contains(strValue[index]) )
return false;
return true;
}
}
短字符串的性能
具有IndexOf
var chrono = new Stopwatch();
chrono.Start();
for ( int index = 0; index < 10000000; index++ )
{
"This a test string".ContainsOnlyChars('a','b','c','d');
}
chrono.Stop();
Console.WriteLine("Elapsed: " + chrono.ElapsedMilliseconds);
Debug Elapsed: 510
Release Elapsed: 178
随便
Debug Elapsed: 747
Release Elapsed: 281
全部
Debug Elapsed: 1193
Release Elapsed: 644
使用ToLookup
Debug Elapsed: 1542
Release Elapsed: 870
不包含
Debug Elapsed: 2195
Release Elapsed: 1423
带字典
Debug Elapsed: 2947
Release Elapsed: 1900
大字符串性能
具有IndexOf
var random = new Random();
string str = "";
for ( int index = 0; index < 10000; index++)
str += (char)random.Next(48,127);
chrono.Start();
for ( int index = 0; index < 10000000; index++ )
{
str.ContainsOnlyChars('a','d','e','f','g','h');
}
chrono.Stop();
Console.WriteLine("Elapsed: " + chrono.ElapsedMilliseconds);
Release Elapsed: 327
随便
Release Elapsed: 469
全部
Release Elapsed: 3733
使用ToLookup
Release Elapsed: 4280
不包含
Release Elapsed: 180562
带字典
Release Elapsed: 284176
Fiddle Snippet Benchmark
注意事项
设计精良的for
循环将始终比任何foreach或Linq更快,更不贪心。
证明在IL代码中。
Foreach旨在忘记可能会生成错误的索引管理,但速度稍慢一些。
Linq旨在减少行数并提高可维护性并降低复杂性,但它需要大量的字节,赫兹和时间。
本文链接:https://www.f2er.com/3130324.html