字符串片段组合拼图

时间:2015-06-19 05:22:36

标签: java

假设我给出了一个字符串片段列表。两个片段可以在其重叠的子串上连接。

e.g。

“悲伤”和“den”=“saden”

“fat”和“cat”=不能合并。

示例输入:

aw是poq qo

示例输出:

awas poqo

那么,编写一个方法的最佳方法是找到可以通过组合列表中的字符串来生成的最长字符串。如果字符串是无限的,则输出应为“无限”。

public class StringUtil {

    public static String combine(List<String> fragments) {
        StringBuilder combined = new StringBuilder();
        for (int i = 0; i < fragments.size(); i++) {
            char last = (char) (fragments.get(i).length() - 1);
            if (Character.toString(last).equals(fragments.get(i).substring(0))) {
                combined.append(fragments.get(i)).append(fragments.get(i+1));
            }
        }
        return combined.toString();
    }
}

这是我的JUnit测试:

public class StringUtilTest {

    @Test
    public void combine() {
        List<String> fragments = new ArrayList<String>();
        fragments.add("aw");
        fragments.add("was");
        fragments.add("poq");
        fragments.add("qo");
        String result = StringUtil.combine(fragments);
        assertEquals("awas poqo", result);
    }
}

这段代码似乎不适用于我...它返回一个空字符串:

org.junit.ComparisonFailure: expected:<[awas poqo]> but was:<[]>

我怎样才能让它发挥作用?而且我怎么能让它检查无限的字符串?

2 个答案:

答案 0 :(得分:0)

我不明白fragments.get(i).length() - 1应该如何成为char。你有意识地将它投入使用,但我不能为我的生活告诉你那个目的是什么。一串长度&lt; 63将转换为ASCII(Unicode?)字符,而不是字母。

我认为你的意思是将一个片段中的最后一个字符与另一个片段中的第一个字符进行比较,但我认为这不是代码所做的。

我的有用答案是撤消一些链接方法(function().otherFunction()),将结果存储在临时变量中,然后使用调试器逐步执行。将问题分解为您理解的小步骤,并验证代码是否正在执行您认为应该在每个步骤中执行的操作。一旦它工作,然后回到链接。

编辑:好吧,我很无聊,我喜欢教学。这有点像家庭作业,所以我不会给你任何代码。

1)方法链接只是方便。你可以(而且应该)这样做:

String tempString = fragments.get(i);

int lengthOfString = tempString.length() - 1;

char lastChar = (char) lengthOfString;//WRONG

等。 这使您可以查看中间步骤,并了解您正在做什么。你实际上是取一个字符串的长度,比如3,然后将整数转换为Char。你真的想要字符串中的最后一个字符。如果不使用方法链接,则必须声明一个中间变量类型,这当然会迫使您考虑实际返回的方法。这就是我告诉你放弃方法链接直到你熟悉这些功能的原因。

2)我猜你写这个函数的时候,编译器抱怨它不能从int隐式地转换为char。然后,您显式地转换为char以使其闭合并编译。而现在你正在试图找出它在运行时失败的原因。我们的教训是在学习的同时收听编译器。如果它在抱怨,那你就搞砸了。

3)我知道还有别的东西。调试。如果你想编码,你需要学习如何做到这一点。大多数IDE都会为您提供设置断点的选项。了解如何使用此功能并逐行“逐步”执行代码。想一想你正在做什么步骤。记下短两个字母对的算法,并在纸上手工执行,一次一步。然后一步一步地看看代码是什么,直到你看到它做了一些你觉得不对的东西。最后,修复没有给出所需结果的部分。

答案 1 :(得分:0)

看看你的单元测试,答案似乎很简单。

public static String combine(List<String> fragments) {
    StringBuilder combined = new StringBuilder();
    for (String fragment : fragments) {
        if (combined.length() == 0) {
            combined.append(fragment);
        } else if (combined.charAt(combined.length() - 1) == fragment.charAt(0)) {
            combined.append(fragment.substring(1));
        } else {
            combined.append(" " + fragment);
        }
    }
    return combined.toString();
}

但是看看你的inqusition例子,你可能正在寻找类似的东西,

public static String combine(List<String> fragments) {
    StringBuilder combined = new StringBuilder();
    for (String fragment : fragments) {
        if (combined.length() == 0) {
            combined.append(fragment);
        } else if (combined.charAt(combined.length() - 1) == fragment.charAt(0)) {
            int i = 1;
            while (i < fragment.length() && i < combined.length() && combined.charAt(combined.length() - i - 1) == fragment.charAt(i))
                i++;
            combined.append(fragment.substring(i));
        } else {
            combined.append(" " + fragment);
        }
    }
    return combined.toString();
}

但请注意,对于您的测试,它会生成aws poq,这似乎是合乎逻辑的。