附加到智能子串算法的额外单词

时间:2015-09-16 21:51:47

标签: java algorithm

我正在研究CareerCup问题:

  

“智能子串”编写一个最多需要30个字符的函数   从一个字符串,但没有切词。

     

完整描述:“拥有时尚的客房和系泊设施   娱乐船,Room Mate Aitana是一家建于2013年的设计师酒店   在阿姆斯特丹的IJ河的一个岛上。“

     

前30个字符:“拥有时尚的房间和mo”

     

更聪明的方法(最多30个字符,没有单词被打破):“特色   时尚的客房和“

这是我的代码。我的逻辑是,我只在附加后添加字符串,它少于30个字符。

public static String substring(String sentence) {
    StringBuffer subString = new StringBuffer();
    String[] splitStr = sentence.split(" ");
    for(String s : splitStr){
        if(subString.append(" " + s).length() < 30) {
            continue;
        } else {
            return subString.toString();
        }
    }
    return subString.toString();
}

这是我的意见:

    String s = "Featuring a stylish room thatsssss is almost";
    System.out.println("Count: " + substring(s).length());
    System.out.println("Result: " + substring(s));

输出:

Count: 35
Result:  Featuring a stylish room thatsssss

第五个单词thatsssss正在绊倒我的算法,但我想这是有道理的,因为在else-statement中,单词已经附加在条件检查中。

我的问题是 - 如何在追加之后检查的条件并且不在追加中附加?

3 个答案:

答案 0 :(得分:3)

为什么你喜欢这个?

    if(subString.append(" " + s).length() < 30)

这里你将s附加到字符串,即使长度大于30.假设你当前的长度是28,下一个单词是test。所以它会将测试附加到你的subString,然后检查它的大小,它将大于30,所以它将转到else分支。但是因为它已经附加了测试词,所以为时已晚。所以要解决这个问题,你应该检查当前的字大小是否会使你的子字符串大小大于30,如下所示

    if(subString.length() + s.length() + 1 <= 30){
        subString.append(" "+s.length());
    } else {
     ...  //same code
    }

答案 1 :(得分:3)

不要拆分字符串并重建它,只需使用lastIndexOf()找到截止点之前(或之前)的最后一个空格。

public static String truncate(String text, int length) {
    if (text == null || text.length() <= length)
        return text;
    int idx = text.lastIndexOf(' ', length);
    return text.substring(0, (idx != -1 ? idx : length));
}

至于性能,搜索为O(5.1)(平均字长为5.1),Java 1-6的子字符串为O(1),Java 7+的子字符串为O(n)(副本) char[]),n是最大值。长度。使用split()的实施也是O(n),但n是全文长度,因此此方法 更快。

测试

String text = "Featuring stylish rooms and moorings for recreation boats, Room Mate Aitana is a designer hotel built in 2013 on an island in the IJ River in Amsterdam.";
for (int i = 0; i <= 40; i++) {
    System.out.printf("%2d: %s%n", i, truncate(text, i));
}

输出

 0: 
 1: F
 2: Fe
 3: Fea
 4: Feat
 5: Featu
 6: Featur
 7: Featuri
 8: Featurin
 9: Featuring
10: Featuring
11: Featuring
12: Featuring
13: Featuring
14: Featuring
15: Featuring
16: Featuring
17: Featuring stylish
18: Featuring stylish
19: Featuring stylish
20: Featuring stylish
21: Featuring stylish
22: Featuring stylish
23: Featuring stylish rooms
24: Featuring stylish rooms
25: Featuring stylish rooms
26: Featuring stylish rooms
27: Featuring stylish rooms and
28: Featuring stylish rooms and
29: Featuring stylish rooms and
30: Featuring stylish rooms and
31: Featuring stylish rooms and
32: Featuring stylish rooms and
33: Featuring stylish rooms and
34: Featuring stylish rooms and
35: Featuring stylish rooms and
36: Featuring stylish rooms and moorings
37: Featuring stylish rooms and moorings
38: Featuring stylish rooms and moorings
39: Featuring stylish rooms and moorings
40: Featuring stylish rooms and moorings for

答案 2 :(得分:0)

在 JavaScript 中,你可以这样做:

<块引用>

算法:不要尝试断开或连接字符串,只需检查 找到索引k处的单词之前的空格索引

function main(str = "You have to rise and shine even in the darkness", k = 19) 
{
  let idx = str.lastIndexOf(" ", k);
  const smartSubStr = str.substring(0, idx);
  return smartSubStr;
}
main();