1

I need some help figure this one out. I need to search a string within a string and return the number of occurrences. I have tried the code below and it works and i also tried to use a regex and it worked but my teacher said to pretend that i can't use the indexOf or the regex. I know there have been some similar questions but that didn't help me much since they all use IndexOf or regex. So any ideas please?

What I have tried:

     namespace ConsoleApplication3
    { 
    class Program
        {

          static void Main(string[] args)
           {
              string s1 = "hellohjhghello";
              string s2 = "he";
              var r = Occurrences(s1, s2);
              Console.WriteLine("{0} is repeated {1} times", s2, r);
           }

   static int Occurrences(string s1, string s2)
    {
        int count = 0;
        int pos = 0;
        while((pos = s1.IndexOf(s2,pos)) > -1)
            {
            count++;
            pos += s2.Length;
            }
        return count;
       }
   }
 }  

EDIT: I don't know what my teacher expects me to so but in another exercise I did a search for a char in string. He said to do something similar but for a string. My previous exercise goes like this:

     class ex3
{
    static void Main(string[] args)
    {
        string str = "aaabekldfj";
        char letter = 'a';
        var r = Occurrences(str, letter);
        Console.WriteLine("The letter '{0}' from string '{1}' has {2} occurrences", letter, str,r);
    }
    static int Occurences(string str, char letter)
    {
        int repeat = 0;
        for(int i=0; i< str.Length; i++)
        {
            if (str[i] == letter)
                repeat++;
        }
        return repeat;
    }
}
O.Pop
  • 21
  • 2
  • @Brandon Not really since that was actually counting the occurrences of a character in a string, and not a substring. – juharr Nov 28 '16 at 17:51
  • 2
    I think your teacher expects you to write your own version of `IndexOf`? –  Nov 28 '16 at 17:53
  • What should the result of "aa" in "aaaa" be? 2 or 3? – juharr Nov 28 '16 at 17:55
  • Yeah, that's a completely different question. I'd ask "How do I write my own version of IndexOf()", and just incorporate that here if you really need to. What work have you put into making your own version of that? – Mason11987 Nov 28 '16 at 17:56
  • yeah i already saw the answers for that question and it only works for one character not a string – O.Pop Nov 28 '16 at 17:58
  • @juharr You can change it to be a substring and not a character. – Brandon Nov 28 '16 at 18:06
  • @Brandon But a lot of the answers took the fact that it was a search for one character into account. Also doubt the teacher that won't let them use `IndexOf` would be OK with a solution that uses `Replace`. – juharr Nov 28 '16 at 18:09
  • The trick is to use replace("needle", "") and compare the resulting length. – TaW Nov 28 '16 at 18:14
  • Note that the linked question is terrible (as it suggests asking about characters) and most of the answers are wrong (as they fall for it). Also: All Linq answers soon get way too slow or even crash for longer strings. So what starts as a duplicate turns into where is Waldo, ie where is @Dispersia's solution..?? – TaW Nov 28 '16 at 18:23
  • Maybe you teacher's idea here for you is to get a bit of knowledge of the nature of substring search algorithms and how they internally work? You may take a look at KPM algorithm: https://en.m.wikipedia.org/wiki/Knuth–Morris–Pratt_algorithm. The idea of the algorithm is great and it can be easily implemented – oldovets Nov 28 '16 at 20:07
  • And here is the the fastest one: https://en.m.wikipedia.org/wiki/Boyer–Moore_string_search_algorithm – oldovets Nov 28 '16 at 20:24

3 Answers3

1

Without indexof and regex and keeping it simple (but not fast), you can do following

static int OccurrencesAdvanced(string s1, string s2)
{
    var result = 0; 
    for (var i = 0; i <= (s1.Length - s2.Length); i++)
    {
        var tested = s1.Substring(i, s2.Length);
        if (string.Compare(tested, s2) == 0)
        {           
            i += Math.Max(1, s2.Length - 1);
            result++;
        }   
    }   
    return result;
}
tym32167
  • 4,741
  • 2
  • 28
  • 32
1

Why not keep it simple?

string compareText = "hello! This is a string to check hello's in this string!";
string compareWord = "hello";

int occurrences = (compareText.Length - compareText.Replace(compareWord, string.Empty).Length) / compareWord.Length;
Dispersia
  • 1,436
  • 9
  • 23
0

Here is my idea what first came in my mind. I don't know currently where are you in your studies so this solution might not good for you.

 class Program
    {
        static void Main(string[] args)
        {
            var s1 = "hellohjhghello";
            var s2 = "lo";
            var occurence = 0;
            Occurrences(s1, s2, ref occurence);
            Console.WriteLine("{0} is repeated {1} times", s2, occurence);
            Console.ReadLine();
        }

        static void Occurrences(string s1, string s2, ref int occurence)
        {
            var index = s1.IndexOf(s2);
            if (index > -1)
            {
                occurence++;
                s1 = s1.Substring(index + s2.Length);
                Occurrences(s1, s2, ref occurence);
            }
        }
    }
Newboy
  • 57
  • 2
  • 5