2011-06-01 77 views
20

我的第一个实施的想法是做简单:什么是最快的方式来检查字符串是否在C#中有大写字母?

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

但也许有另一种更快的方式做到这一点?

+3

我会考虑这个“足够快”。 – BoltClock 2011-06-01 01:19:21

+1

我认为这是一个好方法,你可以使用LINQ来完成for循环的工作,但生成的代码将是等效的。您还可以测试原始字符串是否与转换为小写字符串的字符串不相同,但是我期望该字符串的性能较差,因为它始终需要全部遍历字符串。 – Clayton 2011-06-01 01:23:58

+0

使用LINQ代替for循环可能会出现一些性能问题 – VisualBean 2013-10-08 12:40:18

回答

39

你可以使用LINQ减少到

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

+1

e再次降低到: return!string.IsNullOrEmpty(password)&& password.Any(char.IsUpper); – 2013-05-21 20:51:21

+0

所以,如果你有字符串“12345”,那么HasUpperCase仍然会返回true ..需要检查AZ – Allie 2013-08-05 14:35:54

+0

@SmartPCInformatica您的评论似乎不正确[DotNetFiddle示例](https://dotnetfiddle.net/ shsyaG)。 – 2015-01-18 20:15:09

9

Cheating from here:

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

    return str != str.ToLower(); 
} 
+0

需要一个空检查。 – BoltClock 2011-06-01 01:23:36

+0

这个效率如何?您只需制作一个字符串副本即可进行比较。 – Yuck 2011-06-01 01:24:08

+0

@BoltClock:谢谢! – 2011-06-01 01:24:38

3
bool hasUpperCase(string str) { 
    if (string.IsNullOrEmpty(str)) 
     return false; 
    return Regex.IsMatch(str, "[A-Z]"); 
} 

免责声明:我不是正则表达式的专家,但我测试这跟弦Testing, testinG, and tesTing,所有评估为true。然而,它也被评估为字符串TESTING,你可能想也可能不想。

2

代码对我来说看起来很好,因为你要求性能,可以通过从反面添加条件检查来减少从O(n)到O(n/2 +〜1)的for循环。

否则,您可以检查两个后续元素,然后将i递增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; 

}

恕我直言,这个技巧可能有助于回答算法采访时,并没有得到太多的表现。

5

好 - 时间为新的真相!

这是对字符串中任何大写字母的测试。

该字符串保证在第一个60K字符内没有任何大写字符。 (我从random.org创建的字符串)

我通过随机化将64K字符串传递给测试函数来防止编译器中的字符串替换优化。

所有的时间都非常严格地围绕实际测试,并且不包括函数调用时间。

我跑了测试一次,10次,并再次10000次,并平均每组测试的时间。

我跑在64位的测试运7与i3-2100 CPU @ 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 = 3.000 ms
  2. 10 x = 0.860 ms
  3. 10,000 x = 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×= 2.000毫秒
  2. 10×= 1.597毫秒
  3. 10,000×= 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×= 1.000毫秒
  2. 10×= 0.357毫秒
  3. 10,000×= 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×= 0.000毫秒
  2. 10×= 0.137毫秒
  3. 10,000×= 0.184毫秒

有趣。

我希望这statisfies RK先生;)

+0

你知道情况1和4是相同的,但有不同的计时结果吗? – 2014-04-02 09:36:56

+0

必须复制了错误的代码 - 很久以前,我不记得我为case 4做了什么...对不起! – 2014-04-02 13:51:59

+1

好吧,因为我被Koritnik先生(sob)严重殴打,所以我在上面更新了我的回答...;) – 2014-04-02 16:02:40

0
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层谁检查任何字符串的第一个字母,它从上转换简单的方法来降低和virse verca ....希望会帮助你。

相关问题