2015-11-29 2 views
2

Я решил проблему, указанную ниже, она отлично работает, но кажется громоздкой и не очень эффективной. Я ищу способы улучшить его и получить более элегантное решение, любые предложения, как я могу его улучшить? Любые советы оценили. Спасибо!Элегантное решение для пользовательской замены java string

Задача: Приведенная строка возвращает строку, в которой каждый вид строчного слова «есть» заменен на «нет». Слово «есть» не должно предшествовать или сопровождаться буквой - так, например, «is» в «this» не учитывается.

Тесты:

notReplace("is test") → "is not test" 
    notReplace("is-is") → "is not-is not" 
    notReplace("This is right") → "This is not right" 
    notReplace("This is isabell") → "This is not isabell" 
    notReplace("")→ "" 
    notReplace("is") → "is not" 
    notReplace("isis") → "isis" 
    notReplace("Dis is bliss is") → "Dis is not bliss is not" 
    notReplace("is his") → "is not his"  
    notReplace("xis yis") → "xis yis" 
    notReplace("AAAis is") → "AAAis is not" 

Мое решение:

public static String notReplace(String str) { 
    String result=""; 
    int begin = 0; 
    if (str.equals("is")) 
     return "is not"; 
    int index = str.indexOf("is"); 
    if (index==-1) 
     return str; 
    while (index>-1){ 
      if (index+begin==0 && !Character.isLetter(str.charAt(index+2))){ 
       result += "is not"; 
      begin = index+2; 
      index = str.substring(begin).indexOf("is"); 
      } 
      else if (index+begin==0 && Character.isLetter(str.charAt(index+2))){ 
       result += str.substring(begin,begin+index)+"is"; 
       begin += index+2; 
       index = str.substring(begin).indexOf("is"); 
      } 
      else if (index+begin == str.length()-2 && !Character.isLetter(str.charAt(index+begin-1))){ 
       result += str.substring(begin, begin+index)+"is not"; 
       return result; 
      } 
      else if(!Character.isLetter(str.charAt(index+begin-1))&&!Character.isLetter(str.charAt(index+begin+2))){ 
       result += str.substring(begin,begin+index)+"is not"; 
       begin += index+2; 
       index = str.substring(begin).indexOf("is"); 
      } 
      else { 
       result += str.substring(begin,begin+index)+"is"; 
       begin += index+2; 
       index = str.substring(begin).indexOf("is"); 
      } 
     } 
     result += str.substring(begin); 
     return result; 
} 
+0

Вы можете прочитать о так называемых «регулярных выражений». Они обычно используются для соответствия и замены ввода на основе определенных условий. –

+0

Спасибо за совет @still_learning, я обязательно перепишу свое решение с помощью регулярного выражения, неудивительно, если есть одно линейное решение, у меня просто не было много опыта использования их. –

+0

Я был бы признателен за решения, которые работают для всех упомянутых тестовых примеров, а не только для некоторых из них, иначе предлагаемое решение не является вариантом. Благодаря! –

ответ

2

Вы должны использовать Pattern.compile, а затем replaceAll. Я попытался написать regex, но я потерпел неудачу.

Так что вы должны сделать что-то вроде этого:

class Replacer { 
    static Pattern isPattern = Pattern.compile("...(is)..."); // here you have to figure out the right pattern 

    public static String notReplace(String input) { 
     return isPattern.matcher(input).replaceAll("is not"); 
    } 
} 

Я думаю, что это самое чистое решение, и гораздо быстрее, чем input.replaceAll, который компилирует Pattern каждый раз.

Как регулярное выражение, вероятно, вы должны использовать н как [^\\p{Alphanum}](is)[^\\p{Alphanum]

UPDATE

Вы должны использовать так называемые граница слова петь \b поэтому выражение должно выглядеть следующим образом: Pattern.compile("\\b(is)\\b") и проходит все ваших тестов :-)

+0

Спасибо за вход k0ner, вот что я подумал, осталось только выяснить правильное регулярное выражение. –

+0

см. Обновление. Я наконец понял правильное регулярное выражение – k0ner

+0

Спасибо k0ner, хорошая работа, это именно то, что мне было нужно, окончательный код: public String notReplace (String str) { return str.replaceAll ("\\ bis \\ b", " не является"); } –

3

Это решение работает для большинства ваших примеров:

public String notReplace(String str) { 
    // Add surrounding whitespace in case of an "is" at the beginning or end 
    str = " " + str + " "; 
    // Do replacement 
    String result = str.replaceAll(" is ", " is not "); 
    // Other replacements... 
    // result = result.replaceAll("", ""); 

    return result.trim(); // Remove added whitespaces again using trim() 
} 

Для примеров, которые не заменены с этим кодом вам нужно добавить дополнительные строки кода. Или загляните в регулярные выражения, - сказал он.

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

+0

Благодарю рекапиктуры, я ценю ваш вклад, но ваше решение охватывает только один сценарий для случая («есть») и не будет работать во всех других тестах, таких как «1is», «+ 123» и т. Д. Это не просто так просто. –

+0

Это выход я получаю от моего теста: не проверить Isis Это не правильно Это не Изабелл не ISIS Dis не блаженство не не его Xis yis AAAis не является – regapictures

+0

regapictures, это правильно, но это решение по-прежнему не обрабатывает «is», разделенное символами небелых пробелов. –

0

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

str.replaceAll("([^a-zA-Z]|^)is([^a-zA-Z]|$)", "$1is not$2"); 
0

С @ k0ner чьей помощи выяснили одно решение строки:

public String notReplace(String str) { 
    return str.replaceAll("\\bis\\b","is not"); 
} 
0

Все данные слова в вашем примере можно организовать с этим ответом и в случае вы получите что-то вроде «Это не Isabell является» то этим последним «является» будет заменен только вместо того, чтобы заменить «является» с «не».

String ss = word.replaceAll("\\bis\\b(?!=*.not\\b)", "is not"); 

Пример link

+0

спасибо за ввод, но из требования вы увидите, что первое «есть» также должно быть заменено (все «есть», которым не предшествует и следует буква.) –

+0

Вы хотите, чтобы это было похоже на «» Это не isabell is "' - - -> '" Это не не isabell, а не '' ??? –

+0

Да @ Мадушан Перера, это то, чего хочет автор проблемы. Это просто проблема практики, а не реальная возможность использования. –

Смежные вопросы