Как объединить две строки, чтобы игнорировать дублируемую подстроку

86
9

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


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

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


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

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

спросил(а) 2020-04-04T00:20:46+03:00 3 месяца назад
1
Решение
110

Ваша ошибка находится в строке


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

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

s = s1+s2.substring(L);

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

ответил(а) 2020-04-04T00:36:28.865514+03:00 3 месяца назад
86

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

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

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

ответил(а) 2020-04-04T00:20:46+03:00 3 месяца назад
80

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


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;

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


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

ответил(а) 2020-04-04T00:20:46+03:00 3 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема