检查字符串是否“大部分”为大写字母的快速方法
Fast way to check if string is `mostly` capital
我正在用 C# 为聊天室编写一个机器人,我想检测一条消息是否包含太多大写字母。如果消息的大写字母总数超过消息总长度的 one-third
并且总长度大于 13
,则消息包含太多大写字母。这是为了防止较小的邮件被标记。
现在我正在遍历每个字符并查看它是否为大写。这对于长度合理的消息来说很好。但是,如果您遇到垃圾邮件发送者或巨魔,他们不会总是 post 合理长度的消息。最大字符数限制为 2000
,我无法更改。使用我的方法,它开始停滞在 500+
个字符附近。这给了垃圾邮件发送者足够的时间来粘贴消息并再次发送,有效地淹没了聊天,而机器人却在努力跟上。
我目前拥有的代码:
bool isMostlyUpper = (message.Count(c => char.IsUpper(c)) >= message.Length * 0.3f) && message.Length > 13;
我无法将消息与 string.ToUpper()
进行比较,因为我仍然想检测消息是否主要是大写而不是全部大写。
有没有一种方法可以在不遍历每个字符的情况下做到这一点?或更快获得结果的方法?我可以添加检查以查看消息是否 > 500
但有时会有 500+
可以通过的长消息。
有没有人有什么巧妙的解决办法?谢谢。
如果在达到条件时跳出 foor 循环,在某些情况下会节省一些时间
int count = 0;
float maxLenght = message.Length * 0.3f;
bool isMostlyUpper = false;
foreach (char c in message)
{
if (char.IsUpper(c))
{
count++;
}
if(count >= maxLenght)
{
isMostlyUpper = true;
break;
}
}
您还可以跟踪最后一条被标记的消息,并将其与收到的新消息进行比较,这样可以阻止人们发送垃圾邮件,并且您不必多次重新计算同一消息。
消息太长时开始跳过字符
private static bool IsMostlyUpper (string message)
{
if (message.Length > 13) {
int step = 1 + message.Length / 100; // integer division.
// 1 for message length < 100
// 2 for message length < 200
// 3 for message length < 300
int limit = message.Length / step / 3;
int upperCase = 0;
for (int i = 0; i < message.Length; i += step) {
if (Char.IsUpper(message[i])) {
upperCase++;
if (upperCase >= limit) {
return true;
}
}
}
}
return false;
}
使用更大的除数来测试更多的字符。
如果您认为非常聪明的机器人可以欺骗您的算法,您还可以创建一个随机除数
private static Random _random = new Random(); // static field
创建除数
int divisor = _random.Next(150, 200);
int step = 1 + message.Length / divisor;
但这只是节省几微秒的复杂性!
我正在用 C# 为聊天室编写一个机器人,我想检测一条消息是否包含太多大写字母。如果消息的大写字母总数超过消息总长度的 one-third
并且总长度大于 13
,则消息包含太多大写字母。这是为了防止较小的邮件被标记。
现在我正在遍历每个字符并查看它是否为大写。这对于长度合理的消息来说很好。但是,如果您遇到垃圾邮件发送者或巨魔,他们不会总是 post 合理长度的消息。最大字符数限制为 2000
,我无法更改。使用我的方法,它开始停滞在 500+
个字符附近。这给了垃圾邮件发送者足够的时间来粘贴消息并再次发送,有效地淹没了聊天,而机器人却在努力跟上。
我目前拥有的代码:
bool isMostlyUpper = (message.Count(c => char.IsUpper(c)) >= message.Length * 0.3f) && message.Length > 13;
我无法将消息与 string.ToUpper()
进行比较,因为我仍然想检测消息是否主要是大写而不是全部大写。
有没有一种方法可以在不遍历每个字符的情况下做到这一点?或更快获得结果的方法?我可以添加检查以查看消息是否 > 500
但有时会有 500+
可以通过的长消息。
有没有人有什么巧妙的解决办法?谢谢。
如果在达到条件时跳出 foor 循环,在某些情况下会节省一些时间
int count = 0;
float maxLenght = message.Length * 0.3f;
bool isMostlyUpper = false;
foreach (char c in message)
{
if (char.IsUpper(c))
{
count++;
}
if(count >= maxLenght)
{
isMostlyUpper = true;
break;
}
}
您还可以跟踪最后一条被标记的消息,并将其与收到的新消息进行比较,这样可以阻止人们发送垃圾邮件,并且您不必多次重新计算同一消息。
消息太长时开始跳过字符
private static bool IsMostlyUpper (string message)
{
if (message.Length > 13) {
int step = 1 + message.Length / 100; // integer division.
// 1 for message length < 100
// 2 for message length < 200
// 3 for message length < 300
int limit = message.Length / step / 3;
int upperCase = 0;
for (int i = 0; i < message.Length; i += step) {
if (Char.IsUpper(message[i])) {
upperCase++;
if (upperCase >= limit) {
return true;
}
}
}
}
return false;
}
使用更大的除数来测试更多的字符。
如果您认为非常聪明的机器人可以欺骗您的算法,您还可以创建一个随机除数
private static Random _random = new Random(); // static field
创建除数
int divisor = _random.Next(150, 200);
int step = 1 + message.Length / divisor;
但这只是节省几微秒的复杂性!