patterncsharpMinor
Counting occurrences of substring in string
Viewed 0 times
substringstringcountingoccurrences
Problem
I need to know how many times a substring occurs in a given string. I figured that I might as well create an extension method:
I'm not sure that the assignment in the
Any and all comments appreciated, the more the better.
public static int Occurences(this string str, string val)
{
string copy = str;
int instancesOf = 0;
int indexOfVal;
while ((indexOfVal = copy.IndexOf(val)) != -1)
{
copy = copy.Remove(indexOfVal, val.Count());
instancesOf++;
}
return instancesOf;
}I'm not sure that the assignment in the
while loop is good practice. Should I change this to compute the value once outside the loop, and once in the loop, like this?int indexOfVal = copy.IndexOf(val);
while (indexOfVal != -1)
{
copy = copy.Remove(indexOfVal, val.Count());
instancesOf++;
indexOfVal = copy.IndexOf(val);
}Any and all comments appreciated, the more the better.
Solution
Your current implementation could be more efficient. Copying the passed in string and chopping it up is probably pretty expensive (I'm not a master of .NET internals though).
Why not
We don't need to remove part of the string, just search again starting at
Here is an example using an overload of
This implementation will count overlapping occurrences (so
If you don't want to count overlapping occurences, you can replace
On why an exception isn't thrown in the case of
If startIndex equals the length of the string instance, the method returns -1.
val.Count()Why not
val.Length? Count() is very inefficient compared to Length.copy = copy.Remove(indexOfVal, val.Count());We don't need to remove part of the string, just search again starting at
indexOfVal + val.Length.Here is an example using an overload of
String.IndexOf:public static int Occurences(this string str, string val)
{
int occurrences = 0;
int startingIndex = 0;
while ((startingIndex = str.IndexOf(val, startingIndex)) >= 0)
{
++occurrences;
++startingIndex;
}
return occurrences;
}This implementation will count overlapping occurrences (so
"bbb".Occurences("bb") will return 2.If you don't want to count overlapping occurences, you can replace
++startingIndex; with:startingIndex += val.LengthOn why an exception isn't thrown in the case of
"foo".Occurrences("o"), from MSDN:If startIndex equals the length of the string instance, the method returns -1.
Code Snippets
val.Count()copy = copy.Remove(indexOfVal, val.Count());public static int Occurences(this string str, string val)
{
int occurrences = 0;
int startingIndex = 0;
while ((startingIndex = str.IndexOf(val, startingIndex)) >= 0)
{
++occurrences;
++startingIndex;
}
return occurrences;
}startingIndex += val.LengthContext
StackExchange Code Review Q#85357, answer score: 8
Revisions (0)
No revisions yet.