如何智能地连接两个字符串以忽略重复的子字符串

时间:2011-11-19 18:15:50

标签: java string-concatenation

我希望智能地连接用户输入,以便它以下列方式删除重复的子字符串。

  • 不安+轻松=不安地
  • concat + catalyst = concatalyst

这是我想要做的,不能弄清楚缺少什么

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 个答案:

答案 0 :(得分:7)

您的错误在

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

您正在连接整个s1加上公共部分,它已经包含在s1中。尝试将其更改为

s = s1+s2.substring(L);

它应该可以工作(不测试)。

答案 1 :(得分:4)

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

问题是s1已经包含了common。这就是你得到两个常见字符串的原因。

但是,您的算法在更常见的情况下不起作用    不安地+ easytogo = uneasylytogo

答案 2 :(得分:3)

这一行是你的问题:

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短,则可以通过在outter循环中使用s2从2个字符串的末尾向后迭代来看到性能改进(无论多么轻微)。可能不值得,但你要求更多建议......