【问题标题】:String Fragment Combinations Puzzle字符串片段组合拼图
【发布时间】:2015-06-19 05:22:35
【问题描述】:

假设我得到了一个字符串片段列表。两个片段可以在它们重叠的子串上连接。

例如

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

"fat" 和 "cat" = 不能组合。

示例输入:

aw 是 poq qo

样本输出:

原来是这样的

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

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:<[]>

我怎样才能让它工作?还有如何让它检查无限字符串?

【问题讨论】:

  • 您的要求不清楚,可能只是拼写错误,但inquisittision 是如何生成inquisition 的?另外,如何在一个列表中组合任意数量的字符串会产生无限的结果?
  • 我想知道什么是“无限”字符串
  • @David Wallace,模式是如果一个项目的最后一个字母与后续项目的第一个字母匹配,而不是组合在一起。
  • 根据该规则,inquisittision 将变为 inquisitision。这就是你的本意吗?

标签: java


【解决方案1】:

我不明白fragments.get(i).length() - 1 应该如何成为char。你显然是故意施放它的,但我一生都无法说出那个目的是什么。长度

我认为您的意思是将一个片段中的最后一个字符与另一个片段中的第一个字符进行比较,但我不认为那是该代码正在做的事情。

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

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

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

String tempString = fragments.get(i);

int lengthOfString = tempString.length() - 1;

char lastChar = (char) lengthOfString;//WRONG

等等。 这让您可以看到中间步骤,并思考您在做什么。您实际上是在获取字符串的长度,例如 3,并将该整数转换为字符。你真的想要字符串中的最后一个字符。当你不使用方法链时,你不得不声明一个中间变量的类型,这当然会迫使你考虑方法实际返回的内容。这就是为什么我告诉你在你熟悉函数之前放弃方法链接。

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

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

【讨论】:

  • 我需要链接它,因为如果它是 4 个元素而不是两个元素,我还能如何比较?您对我正在尝试做的事情是正确的“......将一个片段中的最后一个字符与另一个片段中的第一个字符进行比较,但我不认为那是该代码正在做的事情。”
  • Ron,我知道如何使用调试器,我只是使用方法链接,因为我不知道如何让它比较每个项目。这不是家庭作业。这只是我试图雄心勃勃地解决的一个难题。抱歉,如果您对我提出问题的方式感到不安。
  • @socal_javaguy:我完全没有被冒犯。如果不是家庭作业,我道歉。我经常看到。尽管如此,其余的答案仍然成立:)。我宁愿教人钓鱼。
  • Ron Thompson... 我发帖是想看看其他人会如何解决这个问题。我最初按照 Abishek 的建议使用了 for each,但很困惑。谢谢你的道歉。
【解决方案2】:

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

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();
}

但是看看你的调查例子,你可能正在寻找这样的东西,

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,这似乎是合乎逻辑的。

【讨论】:

  • 谢谢阿比舍克!但是,单元测试失败 org.junit.ComparisonFailure: expected: but was:
  • 您是否使用了与答案相同的代码?因为它在不同的单词之间有一个
  • 是的,我复制并粘贴了您的代码,结果比较失败。
  • 仍然不起作用:org.junit.ComparisonFailure: 预期: 但是: 它应该是“awas poqo”而不是“aws poq”。
  • 第一个代码将给出 awas poqo... 但对于“inquisit”和“tision”,它将是“inquisitision”而不是“inquisiton”。
猜你喜欢
  • 2016-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-25
  • 1970-01-01
相关资源
最近更新 更多