Какой самый быстрый способ проверить, есть ли строка имеет заглавную букву в C #? - PullRequest
21 голосов
/ 01 июня 2011

Моя первая идея реализации заключается в следующем:

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;
}

, но, может быть, есть другой более быстрый способ сделать это?

Ответы [ 6 ]

40 голосов
/ 01 июня 2011

Вы можете уменьшить это значение до

bool HasUpperCase (string str) {
    return !string.IsNullOrEmpty(str) && str.Any(c => char.IsUpper(c));
}

, используя LINQ.

9 голосов
/ 01 июня 2011

Обман здесь:

bool hasUpperCase (string str) {
 if(string.IsNullOrEmpty(str))
     return false;

  return str != str.ToLower();
}
5 голосов
/ 05 августа 2012

хорошо - время новой истины!

Это был тест для любого символа верхнего регистра в строке.

Строка гарантированно не содержит символов верхнего регистра в первых 60К символов. (Я создал строку из random.org)

Я предотвратил оптимизацию подстановки строк в компиляторе путем рандомизации того, какая 64-символьная строка была передана в тестовую функцию.

Все сроки были очень строго соответствуют фактическому тесту и не включали время вызова функции.

Я запускал тест один раз, 10 раз и снова по 10000 раз и усреднял каждый набор времени для каждого теста.

Я провел тест на 64-битной Win 7 с процессором i3-2100 @ 3,1 ГГц

Контрольный пример 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;
    }

Итоговое среднее время:

  1. 1 X = 3000 мс
  2. 10 x = 0,860 мс
  3. 10000 х = 0,821 мс

Контрольный пример 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;
    }

Итоговое среднее время:

  1. 1 x = 2.000 мс
  2. 10 x = 1,597 мс
  3. 10000 х = 1,603 мс

Контрольный пример 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;
    }

Итоговое среднее время:

  1. 1 x = 1.000 мс
  2. 10 x = 0,357 мс
  3. 10000 х = 0,298 мс

Контрольный пример 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;
    }

}

Итоговое среднее время:

  1. 1 x = 0,000 мс
  2. 10 x = 0,137 мс
  3. 10000 х = 0,184 мс

Интересно.

Надеюсь, это будет мистер Р. К.;)

3 голосов
/ 01 июня 2011
bool hasUpperCase(string str) {
    if (string.IsNullOrEmpty(str))
        return false;
    return Regex.IsMatch(str, "[A-Z]");
}

Отказ от ответственности : Я не эксперт по Regex, но я проверил это со строками Testing, testinG, and tesTing,, которые все оценили как истинные.Тем не менее, он также оценивается как true со строкой TESTING, что вы можете или не можете хотеть.

2 голосов
/ 01 июня 2011

Код выглядит хорошо для меня, так как вы запрашиваете производительность, вы можете уменьшить цикл for с O (n) до O (n / 2 + ~ 1), добавив условную проверку с обратной стороны.

В противном случае вы можете проверить два последующих элемента и увеличить i на 2. Очевидно, вам следует проверить i

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;

}

ИМХО, этот совет может помочь в ответах на интервью алгоритма, малоэффективен.

0 голосов
/ 13 февраля 2014
    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 простых метода, которые проверяют первую букву любой строки и конвертируют ее из верхнего в нижний и вирс верка .... надеюсь, это поможет вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...