【问题标题】:Is there a way to search a String of lyrics then substring out the matching phrases有没有办法搜索一串歌词然后子串出匹配的短语
【发布时间】:2018-05-17 21:52:07
【问题描述】:

我需要在歌词中搜索匹配的短语。

例如:

我有这样的歌词。

"是我的人,我知道某事某事某事某事某事她爱你和我 某事某事某事。”


给定下面的搜索词,搜索最接近匹配的歌词并计算子字符串中的字符。我的问题是使用indexOf 找到最接近的匹配返回第一个 SHE。我需要能够子串出关闭匹配的短语。

结果应该打印出来

“她爱我”的最匹配搜索是“她爱你和我”。

索引长度:20

【问题讨论】:

    标签: java string search substring indexof


    【解决方案1】:

    我知道它不是最优化或最有效的。但是,以下代码适用于大多数关键字。

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    import java.util.TreeMap;
    
    public class KeywordSearch {
    
        public static void main(String[] args) {
            System.out.println(getMatchingLyrics("She is the one that I love, "
                    + "I know it something something something something something "
                    + "she loves you and me something something something.", 
                    Arrays.asList("she you".toLowerCase().split(" "))));
        }
    
        private static String getMatchingLyrics(String lyrics, List<String> keywords) {
            String[] lyricWords = lyrics.split(" ");
    
            // Split and get the word index for keyword matches
            Map<Integer, String> lyricEngine = new TreeMap<>();
            for(int i = 0; i < lyricWords.length; i++) {
                String search = lyricWords[i].toLowerCase().replaceAll("[^a-zA-Z0-9]", "");
                if (keywords.contains(search) && !lyricEngine.values().contains(lyricWords[i])) {
                    lyricEngine.put(i, lyricWords[i]);
                }
            }
    
            Integer min = null;
            Integer max = null;
            if (lyricEngine.size() == 1) {
                return lyricEngine.values().iterator().next();
            } else if (lyricEngine.size() <= keywords.size()) {
                List<Integer> coll = new ArrayList<>(lyricEngine.keySet());
                min = coll.get(0);
                max = coll.get(lyricEngine.size() - 1);
            } else {
                // Prepare the difference between the indexes
                Map<Integer, String> set = new TreeMap<>(); 
                List<Integer> keys = new ArrayList<>(lyricEngine.keySet());
                for(int i=0; i <= lyricEngine.size() - keywords.size(); i++) {
                    int j = i + keywords.size() - 1;
                    int diff = keys.get(j);
                    StringBuilder str = new StringBuilder(keys.get(j) + "");
                    for (j = j - 1; j >= i; j--) {
                        diff -= keys.get(j);
                        str.append(',');
                        str.append(keys.get(j));
                    }
                    set.put(diff, str.toString());
                }
    
                // Get the value with minimum difference
                for(String s:set.get(set.keySet().toArray()[0]).split(",")) {
                    int x = Integer.parseInt(s);
                    if (min == null && max == null) {
                        max = x;
                        min = x;
                    } else {
                        if (x > max) {
                            max = x;
                        } else if (x < min) {
                            min = x;
                        }
                    }
                }
            }
    
            // Build the string from indexes
            StringBuilder s = new StringBuilder();
            for (int i = min; i <= max; i++) {
                s.append(lyricWords[i]);
                if (i < max) {
                    s.append(" ");
                }
            }
            return s.toString();
        }
    }
    

    您可以根据需要构建和优化它。解释以 cmets 给出。如果您有任何疑问,请随时在 DM 或 cmets 中问我。

    针对不同的关键字,

    Keyword: she loves me
    Output: she loves you and me
    
    Keyword: I love it
    Output: I love, I know it
    
    Keyword: she is one love
    Output: She is the one that I love,
    

    【讨论】:

    • 非常感谢,这应该让我朝着我需要做的正确方向前进!
    • 我添加了一组需要解析的测试歌词,并提出了一个数组越界异常。
    • 检查它在哪里抛出异常(行号)并调试代码并检查异常前的实际值。并根据需要添加任何条件,例如array.length &gt; 0
    • 可能没有一个关键字与歌词匹配。导致for(String s:set.get(set.keySet().toArray()[0]).split(",")) { 这一行抛出IndexOutOfBoundsException
    • 这一行在这里打破它 for(int i=0; i
    【解决方案2】:

    您可以在 Java 中实现自己的复杂算法,因为在 JDK 中我们没有开箱即用的合适解决方案。但是在 Java 世界中有很多合适的解决方案,您可以尝试使用 Apache Lucene 来解决您的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-05
      • 2018-04-17
      • 1970-01-01
      • 2021-02-21
      • 2011-02-10
      • 1970-01-01
      相关资源
      最近更新 更多