这是我的角色出现限制。
Dictionary<string,int> chracterLimit=new Dictionary<string,int>{{"c",1,"a",2}};
这是我输入的字符串......
var mystring="caac";
在这里,我检查LINQ中字符的出现是否有效,以及是否使用超过允许的限制。
bool checkstringvalid=!mystring
.ToCharArray()
.Select(c => c.ToString())
.GroupBy(g => g)
.ToList()
.ToDictionary(
d => d.FirstOrDefault(),
d => d.Count())
.Any(z => z.Value > chracterGroup[z.Key]);
上述条件的输出是> 它是一个无效的字符串。因为c的出现是2但允许的限制只有1。
当我使用此功能时,批量数据需要更多时间...... 我的问题是如何更容易地检查这个?
你可以通过正则表达式给我一个解决方案吗? 我想象/ / {0,2} / / c {0,1} /
提前致谢!)
答案 0 :(得分:1)
LINQ引擎非常智能,因此您不太可能从目前的性能中获得很大的性能提升。你可以做的一件事是削减不必要的操作。你所拥有的更清晰的版本是:
int s;
bool violation = myString.GroupBy(c => c.ToString())
.Any(g => characterLimit.TryGetValue(g.Key, out s) && s < g.Count());
这消除了从字符串,字符数组,列表到字典的转换。
对于比这更快的事情,你需要抛弃LINQ并采用迭代方法。
答案 1 :(得分:1)
当使用符号工作时,让我们使用字符,而不是字符串(我们不想要过分ToString()
,不是吗?):< / p>
Dictionary<char, int> chracterLimit = new Dictionary<char,int>{
{'c', 1},
{'a', 2}
};
然后让我们检测计数器示例早期,即如果我们有"aaaaaaaaa....aaa"
,我们必须首先阅读 <{em> 3
a
,不是整个字符串:
Dictionary<char, int> actual = new Dictionary<char, int>();
bool checkStringValid = true;
foreach (char c in mystring) {
int count = 0;
if (actual.TryGetValue(c, out count))
actual[c] = ++count;
else
actual.Add(c, ++count);
if (chracterLimit.TryGetValue(c, out var limit)) {
if (count > limit) {
checkStringValid = false; // limit exceeded
break;
}
}
else {
checkStringValid = false; // invalid charcater detected
break;
}
}
以上代码是 speed 的优化;如果您只想寻找更多可读解决方案:
bool checkstringvalid = !mystring
.GroupBy(c => c)
.Any(chunk => chracterLimit.TryGetValue(chunk.Key, out var limit)
? chunk.Skip(limit).Any()
: true);
答案 2 :(得分:1)
您的LINQ表达式中有很多转换。
相反,这种事情怎么样?
bool IsStringCompliant (string str, Dictionary<char><int> limits)
{
var lim = new Dictionary<char><int>(limits); // copy dict, allows re-use
foreach (var c in str) {
if (lim.ContainsKey(c)) {
lim[c] -= 1;
if (lim[c] <= 0) return false;
}
else return <<whatever result you want when a char is not in dict>>
}
return true;
}
然后执行此操作以使用该功能。
var characterLimit = new Dictionary<string,int>{{'c',1,'a',2}};
var mystring="caac";
bool checkstringvalid = IsStringCompliant(mystring, characterLimit);
由于一些原因,这将很快。
char
而不是string
个变量。另外,下一个程序员更容易理解。
答案 3 :(得分:1)
我不知道你为什么要在这里使用正则表达式解决方案。最后,我不会更快。可以说,如果你超越你的简单例子,那就更复杂了。
仅出于演示目的,这是您将原始条件转换为正则表达式:
c
a
^(?![^c\n]*c[^c\n]*c)(?![^a\n]*a[^a\n]*a[^a\n]*a).*$
这里的想法是断言一个违反上述规则的模式:两个c
或三个a
使用否定字符类的负前瞻作为修改后的.
。还有其他方法可以做到这一点。您应该已经确信不要使用正则表达式执行此任务。