1) Without using regular expression
does C# offer any construct for
matching pattern?
Nothing as powerful as regex that gives everything to you in one shot.
2) For Counting individual character
against the string do i need to derive
my own method?
I do not recommend this approach, but I'm stating it just to show that you could use some built in method to achieve it. You could conceivably use String.IndexOf and look for "a" starting from the 0 index, and keep chugging along in a loop while incrementing a counter on positive matches. Then repeat for "e"..."u" but it will be much less efficient than a regex or a for loop.
A better approach would be to just loop over the string char by char and either feed it to your existing switch statement or look it up in some collection.
Since you want to use LINQ, here's how the above for loop idea could be rewritten to fit. Note, this idea is similar to HuBeZa's solution so +1 there. However, I use a list for the look up and use the StringComparison.InvariantCultureIgnoreCase
enumeration to ignore case:
var vowels = new List<string> { "a", "e", "i", "o", "u" };
var query = words.Select(s => new
{
Text = s,
Count = s.Count(c => vowels.Exists(vowel =>
vowel.Equals(c.ToString(),
StringComparison.InvariantCultureIgnoreCase)))
});
foreach (var item in query)
{
Console.WriteLine("String {0} contains {1} vowels", item.Text, item.Count);
}
My original regex response is below.
Regex Approach
There's a better regex solution than the one you're using. I'm not sure if you're aware of it so I felt it warranted a post. In question #1 you said "without using regular expressions," but IMHO that directly conflicts with question #2 where you asked if you had to derive your own method.
You can shorten your code by using the Regex.Matches method and the Count property on the returned MatchCollection:
Regex rx = new Regex("[aeiou]");
// to ignore case use: new Regex("[aeiou]", RegexOptions.IgnoreCase);
string[] words =
{
"aesthetic", "benevolent", "abstract",
"capricious", "complacent", "conciliatory",
"devious", "diligent", "discernible","dogmatic",
"eccentric","fallacious","indifferent","inquisitive",
"meticulous","pertinent","plausible", "reticent"
};
foreach (string input in words)
{
Console.WriteLine("String {0} contains {1} vowels",
input, rx.Matches(input).Count);
}
// if you really want to use LINQ
var query = from s in words
select new
{
Text = s,
Count = rx.Matches(s).Count
};
foreach (var item in query)
{
Console.WriteLine("String {0} contains {1} vowels", item.Text, item.Count);
}
BTW, you can further shorten your original code by changing 2 items:
1) The string array declaration (I've done this in my example above)
2) Make your case statements fall through to the next case label:
switch (c)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
cnt++;
break;
}
EDIT: updated with a LINQ query. It's not much different than what the OP had, just using the Matches approach.