2011-06-01 80 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 ....希望會幫助你。

相關問題