java—在bst中搜索一个单词时,如何找到它出现的时间

2mbi3lxu  于 2021-06-30  发布在  Java
关注(0)|答案(3)|浏览(224)

我有一个从文本文件中弹出的二叉搜索树
当我显示bst时,它是这样的

the                                                              
            in                              was                              
    Minnesota              it              --              --              
--      --      --      stomach      --      --      --      --      
  --  --  --  --  --  --  only  --  --  --  --  --  --  --  --  --

我用这个方法从这个搜索树中的数组中搜索一个单词,如果这个数组中的单词存在于二叉搜索树中,它就会把它搜索出来

public boolean contains(String d)
{
            BSTNode p = root;

  // Not contained if specified string is null
  if (d == null)
    return (false);

  // OK if specified string equals our data
  if ((p.data != null) && p.data.equals(d))
    return (true);

  // OK if contained in left tree
  if ((p.left != null) && p.left.contains(d))
    return (true);

  // OK if contained in right tree
  if ((p.right != null) && p.right.contains(d))
    return (true);

  // Otherwise, it's not OK
  return (false);

}

包含bstnode类中的方法

public boolean contains(String item) {
    int comp = item.compareTo(data);
    if(comp  == 0) return true;
    if(comp < 0 && left != null && left.contains(item)) return true;
    if(comp > 0 && right != null && right.contains(item)) return true;
    // no matching node was found
    return false;
}

我主要是这样用的

for (int i = 0; i < len; i++) {

            t = array[i];

            if (btree.contains(array[i]) == true) {
                System.out.println(t);

            }

        }

输出

was
in
it
was
the
only
the
the
was
in
in
the
the
the
was
only
the

我怎么能这样输出
仅限:2
是:4
信息技术:1
输入:3
答案:7
...
所以我对代码的理解是,它将每个节点中的所有单词分开检查,而不是在所有节点中搜索一个单词然后移到下一个单词,这样我就得到了这个输出,如果我错了,请纠正我。
希望有人能帮忙!

wlwcrazw

wlwcrazw1#

较不具侵入性的方法是收集以下文字:

List<String> words = new ArrayList<>();
    for (int i = 0; i < len; i++) {
         t = array[i];
         if (btree.contains(array[i])) {
              words.add(t); // <-- collect the words
         }
    }

打印单词/频率:

new HashSet<>(words).forEach(s -> System.out.println(s + ":" + Collections.frequency(words,s)));

或者,直接添加到Map:

Map<String, Integer> word_count = new HashMap<>();
   for (int i = 0; i < len; i++) {
             t = array[i];
             if (btree.contains(array[i])) {
                  word_count.put(s, word_count.getOrDefault(t, 0) + 1);
             }
        } 
   word_count.forEach((key, value) -> System.out.println(key + ":" + value));

如果知道字符串已经在bst上,则更有效的方法是不要再次搜索它。例如:

Map<String, Integer> word_count = new HashMap<>();
   for (int i = 0; i < len; i++) {
             t = array[i];
             if(word_count.contains(t){
                word_count.put(s, word_count.get(t) + 1);
             }
             else if (btree.contains(t)) {
                  word_count.put(s, 0);
             }
        } 
   word_count.forEach((key, value) -> System.out.println(key + ":" + value));
6mw9ycah

6mw9ycah2#

我认为有几点不对劲:
根据定义,bst不能有重复项。每个左节点必须小于根节点;每个右节点必须大于根节点。
先在树的左边搜索。您有些忽略了bst的好处。当前,对于大于根的数据,您的程序将开始搜索左侧节点。然后,程序将搜索左侧节点的最右边的树。只有这样,它才会返回到包含的主类,并从根的右侧继续搜索。
解决方案1:将字符串 Package 到一个类中,该类包含一个整数,如果要添加的新字符串是重复的,则可以递增该整数。
解决方案2:之后

// OK if specified string equals our data
  if ((p.data != null) && p.data.equals(d))
    return (true);

只是

return p.contains()
iyr7buue

iyr7buue3#

不完全确定bst是如何设置的,但是您可以首先创建一个hashmap并执行遍历和更新每个事件。
看看这样的方法

HashMap<String, Integer> map = new HashMap<>(); //initialize this in main or shell function

private void wordOccurrenceTree(TreeNode root) {

   //inorder traversal

    if (root == null) return;
    wordOccurrenceTree(root.left)
    if(map.containsKey(root.value)){ 
         map.put(root.value, map.get(root.value)+1);
    } else {
         map.put(root.value, 1);
    }

    wordOccurrenceTree(root.right);

   //HashMap should be populated with each word and occurrence when method is done recursing

}

相关问题