Как грамотно объединить две строки, чтобы игнорировать дублирующуюся подстроку - PullRequest
4 голосов
/ 19 ноября 2011

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

  • непросто + легко = непросто
  • конкат + катализатор = конкатализатор

Вот что я пытаюсь сделать, не в состоянии выяснить, чего не хватает

public class Concater {
    public String concat(String s1, String s2) {

        String s = s1;
        int L = s2.length();
        while (L > 0) {
            String common = s2.substring(0, L);
            if (s1.endsWith(common)) {
                s = s1+common+s2.substring(L);
                break;
            }
            L--;
        }

        return s;
    }

    public static void main(String[] args) {
        Concater c = new Concater();
        System.out.println(c.concat("uneasy", "easyly")+"|expected:uneasyly");
        System.out.println(c.concat("concat", "catalyst")+"|expected:concatalyst");
    }

}

Вывод

uneasyeasyly|expected:uneasyly
concatcatalyst|expected:concatalyst

Есть ли лучший способ сделать это?

Ответы [ 3 ]

7 голосов
/ 19 ноября 2011

Ваша ошибка в строке

s = s1+common+s2.substring(L);

Вы объединяете все s1 плюс общую часть, которая уже содержится в s1.Попробуйте изменить его на

s = s1+s2.substring(L);

, и он должен работать (хотя и не тестировался).

4 голосов
/ 19 ноября 2011
 s = s1+common+s2.substring(L);

Проблема в том, что общее уже содержится в s1. Вот почему вы получаете две общие строки.

Однако ваш алгоритм не работает в более общем случае неловко + легкого = неловко

3 голосов
/ 19 ноября 2011

Эта строка является вашей проблемой:

s = s1+common+s2.substring(L);

Это должно быть:

s = s1+s2.substring(L);

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

int i = 0;
for ( s1Length = s1.length; i < s1.length(); i++ ) {
    if ( s1.charAt( i ) == s2.charAt( 0 ) {
        boolean matches = true;
        for ( int j = i, k = 0, remaining = s1.length - i; k < remaining; k++, j++ ) {
            if ( s1.charAt( j ) == s2.charAt( k ) ) {
                matches = false;
                break;
            }
        }
        if ( matches ) {
            break;
        }
    }
}
s = s1.substring( 0, i ) + s2;

Обратите внимание, что это не проверено, но перебирает алгоритм ...


Просто подумал еще об одномЕсли вы сравнили длину 1 с длиной 2 перед тем, как сделать это, вы могли бы сделать ее более эффективной, выбрав итерацию во внешнем цикле.Если, например, s2 короче s1, вы можете увидеть улучшение производительности (хотя и незначительное), выполнив итерацию в обратном направлении от конца двух строк с s2 в внешнем цикле.Вероятно, не стоит, но вы попросили больше предложений ...

...