Reputation: 3262
My first implementation idea is to do simply:
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;
}
but maybe there is another faster way to do that ?
Upvotes: 23
Views: 24763
Reputation: 2035
ok - time for the new truth!
This was a test for any upper case character in a string.
The string was guaranteed to not have any upper case character within the first 60K of characters. (I created the string from random.org)
I prevented string substitution optimization in the compiler by randomizing which 64K character string was passed to the test function.
All timings were very strictly around the actual test, and did not include function calling time.
I ran the test once, 10 times, and again for 10,000 times and averaged each set of the timings for each test.
I ran the test on a 64bit Win 7 with i3-2100 CPU @ 3.1 Ghz
Test Case 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;
}
Resulting average time:
Test Case 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;
}
Resulting average time:
Test Case 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;
}
Resulting average time:
Test Case 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;
}
}
Resulting average time:
Interesting.
I hope this statisfies Mr. R. K. ;)
Upvotes: 5
Reputation: 191
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;
}
Here i made 2 simple methods who check the first letter of any string and convert it from Upper to Lower and virse verca .... hope that will help you.
Upvotes: 0
Reputation:
The code looks fine to me, since you ask for performance, you can reduce the for loop from O(n) to O(n/2 + ~1) by adding the conditional checking from the reverse side.
Otherwise you can check two sub-sequent elements and increment the i by 2. Obviously you should check for i < str.Length for the second argument.
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, this tip may help to answer algorithm interview, doesn't get much performance.
Upvotes: 2
Reputation: 2832
bool hasUpperCase(string str) {
if (string.IsNullOrEmpty(str))
return false;
return Regex.IsMatch(str, "[A-Z]");
}
Disclaimer: I am no Regex expert but I tested this with the strings Testing, testinG, and tesTing,
which all evaluated to true. However, it also evaluated to true with the string TESTING
, which you may or may not want.
Upvotes: 3
Reputation: 8108
bool hasUpperCase (string str) {
if(string.IsNullOrEmpty(str))
return false;
return str != str.ToLower();
}
Upvotes: 9
Reputation: 61437
You could reduce that to
bool HasUpperCase (string str) {
return !string.IsNullOrEmpty(str) && str.Any(c => char.IsUpper(c));
}
using LINQ.
Upvotes: 40