Подсчет количества вхождений строки внутри строки

Вот моя попытка этого метода.

Подсчитайте количество совпадений непустой подстроки sub в строке str E.g.

numOccurances("dogmonkeydog","собака") вернет 2

numOccurances("dogmonkeydog","mon") вернет 1

numOccurances("dogmonkeydog", "корова") вернет 0

public static int numOccurrences(String str, String sub) {
    int result = 0;
    int pos = str.indexOf(sub);
    if (pos == -1){
        return result;
    }
    if (sub.length() > str.length()){
        return result;
    }
    if ((str.substring(0, sub.length())).equals(sub)){
        result++;
        String st = str.substring(pos);
        return result + numOccurrences(st, sub); //Line 87
    }
    else{
        String st = str.substring(sub.length());
        return result + numOccurrences(st, sub);
    }
}

Я получаю этот отказ для всех тестов, где результат> 0

java.lang.StackOverflowError
    at java.lang.String.indexOf(String.java:1718)
    at java.lang.String.indexOf(String.java:1698)
    at eecs2030.lab6.RecursiveTasks.numOccurrences(RecursiveTasks.java:77)
    at eecs2030.lab6.RecursiveTasks.numOccurrences(RecursiveTasks.java:87)

Я не уверен, почему мой код никогда не достигает своего базового варианта, любое понимание будет высоко оценено!


person vhjvvvvvvvvvvvvvvvvvvv888    schedule 21.11.2017    source источник
comment
У вас бесконечная рекурсия. Вам нужно отладить, чтобы понять, почему это происходит.   -  person Oleg    schedule 21.11.2017
comment
Почему вы используете рекурсию для решения итерационной задачи?   -  person Jim Garrison    schedule 21.11.2017


Ответы (4)


Это похоже на школьное задание. Итак, я не дам вам прямой ответ.

В следующем фрагменте

result++;
String st = str.substring(pos);
return result + numOccurrences(st, sub); //Line 87

место, где вы создаете st, проблематично. Если str начинается со значения, содержащегося в sub, то str будет равно st. Таким образом, вызов numOccurrences будет таким же, как ваш первоначальный вызов, и поэтому ваша рекурсия не завершится.

Проанализируйте, что нужно передать str.substring в приведенном выше фрагменте.


Надеюсь это поможет!

person anacron    schedule 21.11.2017
comment
Большое спасибо! Я прочитал то, что вы предложили, и нашел проблему. - person vhjvvvvvvvvvvvvvvvvvvv888; 21.11.2017

Третье условие if в вашем методе не нужно.

 if ((str.substring(0, sub.length())).equals(sub))

вы можете просто определить третий случай как

 if(pos>=0)
  {
  result++;
  String newstr = str.substring(pos + sub.length());
  return numOccurrences(newstr,sub);
  }

поскольку, если подстрока найдена, переменная pos будет инициализирована начальным индексом подстроки, вы можете увеличить результат здесь.

затем рекурсивно вызовите метод numOccurences() для остальной части строки. а также объявить переменный результат вне метода.

 import java.util.Scanner;
 class SubString
 {
 String user,subUser;
 Scanner sc=new Scanner(System.in);
 int num;
 static  int result = 0;
 int numOccurrences(String str, String sub) {

  int pos = str.indexOf(sub);
  if (pos == -1){
    return result;
 }
 if (sub.length() > str.length()){
    return result;
  }
  else if(pos >= 0)
  {
   result++;
   String newstr = str.substring(pos + sub.length());
   return numOccurrences(newstr,sub);
   }
 return result;

 }

//constructor
 SubString()
 {
   try{
   System.out.println("Enter string :");
   user=sc.nextLine();
   System.out.println("Enter the substring: ");
   subUser=sc.nextLine();
   num = numOccurrences(user,subUser);
   System.out.println(num);
  }
   catch(Exception e)
   {
    System.out.println(e);
   } 

 }
 public static void main(String...a)
{
 new SubString();
 }
 } 

`

person Namrata Shukla    schedule 21.11.2017

1 : public static int numOccurrences(String str, String sub) {
2 :    int result = 0;
3 :    int pos = str.indexOf(sub);
4 :    if (pos == -1){
5 :        return result;
6 :    }
7 :    if (sub.length() > str.length()){
8 :        return result;
9 :    }
10:    if ((str.substring(0, sub.length())).equals(sub)){
11:        result++;
12:        String st = str.substring(pos);
13:        return result + numOccurrences(st, sub); 
14:    }
15:    else{
16:        String st = str.substring(sub.length());
17:        return result + numOccurrences(st, sub);
18:    }
19:}

Строка 10 – Вы не извлекаете подстроку заданного строкового параметра sub из фактической строки str.
Строка 12 – Вы почти отбрасываете текущую подстроку для следующего вызова, но вы также включаете строку. Пример: monstrfri -> с подстрокой str приведет к strfri, а не fri.

Если вы предпочитаете изменить свою логику, вы можете получить это с помощью простого цикла while pos is index of substring

counter is 0
while pos!=-1
    increment the counter
    trim the current substring found
    extract the next position
    and continue while
person Praveen    schedule 21.11.2017

person    schedule
comment
Вместо рекурсии можно сделать так. - person Saranya Subramanian; 21.11.2017
comment
Спасибо за вашу помощь, однако для этого нас попросили использовать рекурсию в нашем подходе. - person vhjvvvvvvvvvvvvvvvvvvv888; 21.11.2017