代码之家  ›  专栏  ›  技术社区  ›  Jason

是否有比string.split()更有效的方法将字符串拆分为单词?

  •  1
  • Jason  · 技术社区  · 14 年前

    我当前的项目需要在歌曲歌词上运行搜索,这是歌曲对象中的字符串字段。为了提高搜索效率,我在创建歌曲对象时使用 String.split("[^a-zA-Z]"); 若要生成字符串数组,请添加到集合。

    在没有创建数组的中间步骤的情况下,是否有特定的方法将单词添加到集合中?

    4 回复  |  直到 14 年前
        1
  •  1
  •   Denys Kniazhev-Support Ukraine    14 年前

    你在特定歌曲中搜索一些词吗?如果是这样的话,你可能不需要一套,你可以从你得到歌词的那一点开始搜索。为此,可以使用普通regexp,这可能比拆分字符串、将其放入集合并查询集合快一点,然后:

    public class RegexpExample {
    
    public static void main(String[] args) {
        String song = "Is this a real life? Is this just fantasy?";
        String toFind = "is";
    
        Pattern p = Pattern.compile(toFind, Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(song);
    
        while (m.find()) {
            String found = m.group();
            int startIndex = m.start();
            int endIndex = m.end();
    
            System.out.println(found + " at start " + startIndex + ", end " + endIndex);
            //do something with this info...
        }
    }
    

    它将输出:

    Is at start 0, end 2
    is at start 5, end 7
    Is at start 21, end 23
    is at start 26, end 28
    

    但是,如果您搜索不同的歌曲,则可以使用连接它们的歌词 StringBuilder ,然后呼叫 StringBuilder#toString 做整个手术的结果是 toString 方法

        2
  •  1
  •   StriplingWarrior    14 年前

    有没有特定的方法可以将单词添加到没有 创建数组的中间步骤?

    当然,您可以编写一个返回 Iterator 对象,一次输出一个单词。

    但像这样的东西确实不值得优化。您的数组很容易就小到可以放入内存中,它的创建成本不会那么高,垃圾收集器随后将对其进行清理。

        3
  •  0
  •   novalis    14 年前
    StringTokenizer st = new StringTokenizer("the days go on and on without you here");
    HashSet<String> words = new HashSet<String>();
    while (st.hasMoreTokens()) {
        words.add(st.nextToken());
    }
    
        4
  •  0
  •   Powerlord    14 年前

    我不知道效率,但你也可以这样做:

    import java.io.StringReader;
    
    // ...
    
    public static Set<String> getLyricSet(String lyrics) throws IOException {
        StringReader sr = new StringReader(lyrics);
        StringBuilder sb = new StringBuilder();
        Set<String> set = new HashSet<String>();
        int current;
        // Read characters one by one, returns -1 when we're done
        while ((current = sr.read()) != -1) {
            if (Character.isWhitespace(current)) {
                // End of word, add current word to set.
                set.add(sb.toString());
                sb = new StringBuilder();
            } else {
                sb.append((char) current);
            }
        }
        // End of lyrics, add current word to set.
        set.add(sb.toString());
        sr.close();
    
        return set;
    }