Ответ 1
Вы можете уменьшить это до
bool HasUpperCase (string str) {
return !string.IsNullOrEmpty(str) && str.Any(c => char.IsUpper(c));
}
с помощью LINQ.
Моя первая идея реализации состоит в том, чтобы сделать просто:
bool hasUpperCase (string str) {
if(string.IsNullOrEmpty(str))
return false;
for (int i = 0; i < str.Length; i++) {
if (char.IsUpper (str[i]))
return true;
}
return false;
}
но, возможно, есть еще один более быстрый способ сделать это?
Вы можете уменьшить это до
bool HasUpperCase (string str) {
return !string.IsNullOrEmpty(str) && str.Any(c => char.IsUpper(c));
}
с помощью LINQ.
bool hasUpperCase (string str) {
if(string.IsNullOrEmpty(str))
return false;
return str != str.ToLower();
}
ok - время для новой истины!
Это был тест для любого символа верхнего регистра в строке.
Строка гарантировалась, что в первых 60K символов не будет символов верхнего регистра. (Я создал строку из random.org)
Я предотвратил оптимизацию подстановки строк в компиляторе, рандомизировав, какая символьная строка 64 КБ была передана тестовой функции.
Все тайминги были очень строго связаны с фактическим тестом и не включали время вызова функции.
Я провел тест один раз, 10 раз и снова в течение 10 000 раз и усреднил каждый набор таймингов для каждого теста.
Я проверил тест на 64-битной Win 7 с i3-2100 CPU @3.1 Ghz
Тестовый пример 1:
static bool testCaseOne(string str, out double ms)
{
bool result = false;
DateTime start = DateTime.Now;
result = !string.IsNullOrEmpty(str) && str.Any(c => char.IsUpper(c));
ms = (DateTime.Now - start).TotalMilliseconds;
return result;
}
Результирующее среднее время:
Тестовый пример 2:
static bool testCaseTwo(string str, out double ms)
{
bool result = false;
DateTime start = DateTime.Now;
if (string.IsNullOrEmpty(str))
{
ms = 0;
return false;
}
result = Regex.IsMatch(str, "[A-Z]");
ms = (DateTime.Now - start).TotalMilliseconds;
return result;
}
Результирующее среднее время:
Тестовый пример 3:
static bool testCaseThree(string str, out double ms)
{
bool result = false;
DateTime start = DateTime.Now;
if (string.IsNullOrEmpty(str))
{
ms = 0;
return false;
}
for (int i = 0; i < str.Length; i++)
{
if (char.IsUpper(str[i]))
{
result = true;
break;
}
}
ms = (DateTime.Now - start).TotalMilliseconds;
return result;
}
Результирующее среднее время:
Тестовый пример 4:
static bool testCaseFour(string str, out double ms)
{
bool result = false;
DateTime start = DateTime.Now;
if (string.IsNullOrEmpty(str))
{
ms = 0;
return false;
}
for (int i = 0; i < str.Length; i++)
{
if (str[i] > 64 && str[i] < 91)
{
result = true;
break;
}
}
ms = (DateTime.Now - start).TotalMilliseconds;
return result;
}
}
Результирующее среднее время:
Интересно.
Я надеюсь, что это ставит под сомнение г-н Р. К.;)
bool hasUpperCase(string str) {
if (string.IsNullOrEmpty(str))
return false;
return Regex.IsMatch(str, "[A-Z]");
}
Отказ от ответственности: я не специалист по Regex, но я проверил это со строками Testing, testinG, and tesTing,
, которые все оценивались как true. Однако он также оценивается как true с строкой TESTING
, которую вы можете или не хотите.
Код выглядит хорошо для меня, так как вы запрашиваете производительность, вы можете сократить цикл for от O (n) до O (n/2 + ~ 1), добавив условную проверку с обратной стороны.
В противном случае вы можете проверить два субсеквентальных элемента и увеличить я на 2. Очевидно, вы должны проверить я < str.Length для второго аргумента.
bool hasUpperCase (string str) {
if(string.IsNullOrEmpty(str))
return false;
for (int i = 0; i < str.Length; i= i + 2) {
if (char.IsUpper (str[i]))
return true;
if ((i + 1) < str.Length && char.IsUpper (str[i+1]))
return true;
}
return false;
}
IMHO, этот совет может помочь ответить на алгоритм интервью, не получает большой производительности.
public static string Upper_To_Lower(string text)
{
if (Char.IsUpper(text[0]) == true) { text = text.Replace(text[0], char.ToLower(text[0])); return text; }
return text;
}
public static string Lower_To_Upper(string text)
{
if (Char.IsLower(text[0]) == true) { text = text.Replace(text[0], char.ToUpper(text[0])); return text; }
return text;
}
Здесь я сделал 2 простых метода, которые проверяют первую букву любой строки и конвертируют ее из Верхнего в Нижний и девственный verca.... надеюсь, что это поможет вам.