CodingBat starOut, почему использование подстроки не будет работать правильно - PullRequest
0 голосов
/ 15 февраля 2020

Я решаю проблему кодирования на CodingBat.com. Вот вопрос:

Если задана строка и непустая строка слова, вернуть версию исходной строки, в которой все символы заменены на плюсы ("+"), за исключением появления строка слова, которая сохраняется без изменений.

plusOut("12xy34", "xy") → "++xy++" 
plusOut("12xy34", "1") → "1+++++"
plusOut("12xy34xyabcxy", "xy") → "++xy++xy+++xy"

Вот мое попытанное решение:

public String plusOut(String str, String word)
{
  String ret = "";
  for (int i = 0; i < str.length() - word.length() + 1; ++i) {
    if (str.substring(i, i + word.length()).equals(word))
      ret += word;
    else
      ret += "+";
  }
  return ret;
}

Но дает неправильные результаты: слишком много плюсов. Я не понимаю, почему это не должно работать. Я подозреваю, что метод подстроки не возвращает достаточно совпадений, поэтому добавляется знак плюс. Но я не понимаю, почему это так.

enter image description here

Ответы [ 5 ]

1 голос
/ 15 февраля 2020

Я бы использовал StringBuilder для создания результата, чтобы избежать создания нескольких объектов String, поскольку String в java неизменен:

public String plusOut(String str, String word) {
  StringBuilder result = new StringBuilder(str);
  int len = str.length(), wordLen = word.length(), index = 0;
  while(index < len){
    if ( (index <= len-wordLen) && (str.substring(index, index+wordLen).equals(word))){
      index += wordLen;
      continue;
    }
    result.setCharAt(index++, '+');
  }
  return result.toString();
}
0 голосов
/ 15 февраля 2020

Сделайте это следующим образом:

public class Main {
    public static void main(String[] args) {
        // Tests
        System.out.println(plusOut("12xy34", "xy"));
        System.out.println(plusOut("12xy34", "1"));
        System.out.println(plusOut("12xy34xyabcxy", "xy"));
    }

    static String plusOut(String str, String word) {
        StringBuilder sb = new StringBuilder();
        int indexOfWord = str.indexOf(word);
        while (indexOfWord != -1 && indexOfWord <= str.length() - word.length()) {
            if (indexOfWord != -1) {
                for (int i = 0; i < indexOfWord; i++) {
                    sb.append('+');
                }
                sb.append(word);
                str = str.substring(indexOfWord + word.length());
                indexOfWord = str.indexOf(word);
            }
        }
        for (int i = 0; i < str.length(); i++) {
            sb.append('+');
        }
        return sb.toString();
    }
}

Вывод:

++xy++
1+++++
++xy++xy+++xy

Я также рекомендую вам go - Когда использовать StringBuilder в Java

0 голосов
/ 15 февраля 2020

Вы делали несколько вещей неправильно. Я исправил ваш код, хотя, возможно, есть более чистый способ сделать это. Ниже я объясню, что изменилось.

public static String plusOut(String str, String word)
{
    String ret = "";
    for (int i = 0; i < str.length(); ++i) {
        int endIndex = i + word.length();
        if (endIndex < str.length() + 1
                && str.substring(i, i + word.length()).equals(word)) {
            ret += word;
            i = i + word.length() - 1;
        } else
            ret += "+";
    }
    return ret;
}

Первая ошибка заключается в том, что вы не просматриваете весь контент str и поэтому никогда не достигаете последнего символа str.

Другая проблема заключается в том, что, найдя слово, вы не «переходите» к правильному следующему индексу в l oop, но продолжаете цикл по символам найденного слова, что приводит к дополнительным + символов в вашей строке результата.

i = i + word.length() - 1;

В вашем решении приведенное выше приведёт вас к следующему индексу символа внутри str, на который вы должны смотреть. Пример:

В строке 12xy34xyabcxy ищите xy.

Вы найдете, что слово xy начинается с индекса 2 и заканчивается на 3. В этот момент у вас есть строка результата ++xy после добавления к ней найденного word.

Теперь проблема начинается. Вы все еще в конечном итоге перебираете индекс 3 и добавляете дополнительные +, потому что следующая пара символов не соответствует вашему слову.

2 символа после найденного xy также добавьте +, и у вас теперь есть ++xy+++, что неверно.

endIndex < str.length() + 1

endIndex назван в честь того, что это - конечный индекс вашей подстроки.

This check не позволяет нам проверять xy, когда в строке недостаточно символов от текущего индекса до последнего, чтобы составить xy, поэтому мы в итоге добавляем + для каждого оставшегося символа.

0 голосов
/ 15 февраля 2020

Вот ваше решение

    public String plusOut(String str, String word)
{
    String ret = "";
    for (int i = 0; i < str.length();) {
        if (i + word.length()<= str.length() && str.substring(i, i + word.length()).equals(word)) {
            ret += word;
            i+=word.length();
        }
        else{
            ret += "+";
            i++;
        }
    }
    return ret;
}
0 голосов
/ 15 февраля 2020

Сделай так:

public static String plusOut(String str, String word)
{
    String ret = "";
    int i;
    for (i = 0; i < str.length() - word.length() +1 ; i++) {
        if (str.substring(i, i + word.length()).equals(word)) {
            ret += word;
            i += word.length() - 1;
        }
        else
            ret += "+";
    }
    while (i < str.length()) {
        ret += "+";
        i++;
    }

    return ret;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...