【问题标题】:How to find N grams of a word in Java?如何在 Java 中找到一个单词的 N 克?
【发布时间】:2014-04-21 21:15:15
【问题描述】:

例如,如果输入为“name”,minGram 为 1,maxGramSize 为 2,则输出将由 n,a,m,e,na,am,me 组成。如果 minGram=2, maxGram=4 inputWord=name, output = na,am,me,nam,ame,name。

函数签名可以是这样的:

public List<String> generateNGrams(String input, int minGramSize, int maxGramSize)

最初我尝试使用 for 循环来执行此操作,但我发现很难遵循索引。然后我尝试使用笔和纸的递归来解决它,但我仍在努力解决它。有人可以帮我弄这个吗?

【问题讨论】:

  • 这听起来用 for 循环而不是递归来解决它会更自然。如果您发布到目前为止您尝试过的代码,那么您会更容易看到哪里出错了:)
  • 这样做是为了自学还是为了生产?在后一种情况下,请查看lucene.apache.org/core/3_0_3/api/all/org/apache/lucene/analysis/…
  • @Drunix 教育自己,而不是生产。我想在没有库的情况下解决它。不过感谢您的链接。
  • 然后听从动画师的建议,展示你的尝试。
  • 提示:根据您尝试执行的操作,如果您实施文本搜索:不要将所有 n-gram 显式创建到列表中。最好实现一种算法,该算法在文本上滑动q-window,计算每个 q-gram 上的一些哈希,并将这些输入到静态大小的位数组(“bloom 过滤器”)中。由于无论如何您都必须对候选人进行精确比较,这应该会导致更有效的文本检索。

标签: java string algorithm loops recursion


【解决方案1】:

一种解决方案:

private static void addNgrams(final int size, final String input, 
    final List<String> list)
{
    final int maxStartIndex = input.length() - size;
    for (int i = 0; i < maxStartIndex; i++)
        list.add(input.stubString(i, i + size));
}

public List<String> generateNGrams(final String input, final int minSize, 
    final int maxSize)
{
    final List<String> ret = new ArrayList<>();
    for (int size = minSize; size <= maxSize; size++)
        addNgrams(size, input, ret);
    return ret;
}

注意:缺少基本的错误检查(例如,maxSize 大于input 的大小;minSize 大于maxSize;其他);留作练习。

【讨论】:

    【解决方案2】:

    这是一个递归生成 nGram 的程序:此代码还处理尾部gram。

    import java.util.ArrayList;
    
      public class NGrams {
    
      ArrayList<String> nGrams = new ArrayList<String>();
    
      public void generateNGrams(String str, int n) {
    
        if (str.length() == n ) {
            int counter = 0;
            while (counter < n) {
              nGrams.add(str.substring(counter));
              counter++;
            }
            return;
        }
    
        int counter = 0;
        String gram = "";
        while (counter < n) {
            gram += str.charAt(counter);
            counter++;
        }
        nGrams.add(gram);
        generateNGrams(str.substring(1), n);
      }
    
      public void printNGrams() {
        for (String str : nGrams) {
            System.out.println(str);
        }
      }
    
      public static void main(String[] args) {
        NGrams ng = new NGrams();
        ng.generateNGrams("hello world", 3);
        ng.printNGrams();
    
      }
    
    }
    

    输出:

    hel
    ell
    llo
    lo 
    o w
     wo
    wor
    orl
    rld
    ld
    d
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多