【问题标题】:BST in Java -- search Nodes by StringJava中的BST——按字符串搜索节点
【发布时间】:2012-04-19 16:03:48
【问题描述】:

我正在使用以 MovieInfo 对象为键的节点创建二叉搜索树。 MovieInfo 对象是具有三个字段的对象:ID、fullName 和 shortName。二叉搜索树将在包含 IMDB 上列出的每部电影的输入文本文件中存储信息。插入将基于与每部电影随机关联的 ID。搜索功能将让用户输入一个字符串并提取对象的其他数据(短名称、ID 等)。 现在——我遇到的错误是 findExact 方法。 首先,无论我的输入是什么——我都会收到消息“当前节点为空”,这意味着我的起始 currentNode 总是为空。另一个问题是,我不确定如何确保正确初始化我的根节点(在树中搜索的第一个 currentNode)。我有一种感觉,这可能与我的问题有关。 另一个问题可能在于我如何首先插入节点。 作为参考,我在文本输入文件中测试此代码/运行的方式是 IndexTester.java。

更新:好的。现在一切正常。我现在遇到的唯一问题是我的 findExact 方法似乎更改了 MovieInfo 类的 ID 字段。所以我的搜索最终没有奏效。例如,如果我输入:

1568482 2 White Kids with Problems  2 White Kids with Problems
1568487 Disorient   Disorient
1568488 DIY Playgrounds DIY Playgrounds

并搜索“disorient”,返回“1568488 Disorient Disorient”(带有“2 White Kids with Problems”对象的 ID)。另外,由于ID被盗用...DIY Playgrounds无法成功搜索。插入方法有效,但 findExact 方法给我带来了问题。关于什么可能导致 ID 发生这种变化的任何想法?

MovieInfo 类(单独的 .java 文件)——无法编辑

public class MovieInfo {
    public String shortName;
    public String fullName;
    static int ID;
    public String key;

    public MovieInfo(int id, String s, String f) {
        ID = id;
        shortName = s;
        fullName = f;
    }
}

BSTIndex.java -- 我在其中创建内部 BST 的类

import java.util.*;
import java.io.*;

public class BSTIndex extends MovieInfo {

    public Node root;
    public class Node{
        public MovieInfo movie;
        public Node left, right;

    public Node(MovieInfo movie)
    {
        this.movie = movie;
        //this.val = val;
        //this.N = N;
        }
    }

    public BSTIndex()
    /**
     * constructor to initialize the internal binary search tree. 
     * The data element should be an object of the type MovieInfo, described above.
     */
    {   
        super(0, "", "");

    }


    public MovieInfo findExact(String key) {
    return findExact(root, key);
}

private MovieInfo findExact(Node x, String key) {
    if (x == null) return null;
    int cmp = key.compareToIgnoreCase(x.movie.fullName);
    if      (cmp < 0) return findExact(x.left, key);
    else if (cmp > 0) return findExact(x.right, key);
    else              return x.movie;
}

    public void insert(MovieInfo data)
    {
        if (data == null) {return; }
        root = insert(root, data);
    }

    public Node insert(Node x, MovieInfo data)
    {   
        if (x == null) return new Node(data);
        int cmp = data.ID - x.movie.ID;
        if (cmp > 0 )       x.right = insert(x.right, data);
        else if (cmp < 0)   x.left = insert(x.left, data);
        else if (cmp == 0)  x.movie = data;
        return x;
    }
}

IndexTester.java

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;


public class IndexTester {

    // Test program
    public static void main( String [ ] args ) throws FileNotFoundException
    {
        BSTIndex t = new BSTIndex( );
        Scanner scan = new Scanner(new FileInputStream(args[0]));
        long start = System.currentTimeMillis();
        int i=0;

        while(scan.hasNext()){
            String line = scan.nextLine();
            String [] fields = line.split("\t");
            int id = Integer.parseInt(fields[0].trim());
            String shortName = fields[1].trim();
            String fullName = fields[2].trim();
            MovieInfo info = new MovieInfo(id, shortName, fullName);

            t.insert(info);
            i++;
            if(i % 10000 == 0){
                System.out.println("Inserted " + i + " records.");
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("Index building complete. Inserted " + i + 
            " records.Elapsed time = " + (end - start )/1000 + " seconds.");

        Scanner input = new Scanner(System.in);

        System.out.println("Enter search string, end in a '*' for 
            prefix search. q to quit");
        while(input.hasNext()){
            String search = input.nextLine().trim();
            if(search.equals("q")) break;
            if(search.indexOf('*')>0){
                //call prefix search. 

                MovieInfo item = t.findPrefix(search);
                if(item==null) System.out.println("Not Found"); 
                else System.out.println(item.ID + " " + item.shortName + " 
                            " + item.fullName);

            }
            else{
                //call exact search, modify to return MovieInfo
                MovieInfo item = t.findExact(search); 
                if(item==null) System.out.println("Not Found");
                else System.out.println(item.ID + " " + item.shortName + " 
                            " + item.fullName);
            }
        }


    }   
} 

【问题讨论】:

    标签: java string search insert binary-search-tree


    【解决方案1】:

    public class BSTIndex 不应该扩展 MovieInfo,最好是 MovieInfo 应该扩展 Node。

    好的,因此无法修改 MovieInfo,因此我将使用数据填充 MovieInfo 类并将其设置为扩展 Node 类的节点值。

    public class BSTNode extends Node {
        private BSTNode left,right;
        private MovieInfo val;
    
        public void setVal(MovieInfo val){
            this.val=val;
        }
    
        public void setLeft(MovieInfo m){
            left=new BSTNode(m);
        }
        public void setRight(MovieInfo m){
            right=new BSTNode(m);
        }
        //override some of the Node methods
    }
    

    【讨论】:

    • 作为作业的一部分,我无法编辑 MovieInfo.java 文件。你认为它应该在我的公共类 Node 中说它扩展了 MovieInfo 吗?还是有另一种方法可以做到这一点?如果我可以进行更改,我会在 MovieInfo.java 中使用 get() 方法,但不幸的是我不能。
    • 当我这样做时,它在公共 BSTNode(MovieInfo val) 上说“隐式超级构造函数 BSTIndex.Node() 未定义。必须显式调用另一个构造函数。”有什么想法吗?
    • 我已经更新了上面的代码。删除构造函数并添加 setVal 方法。
    • 好的。现在一切正常。我已经更新了我留下的最后一个问题。
    猜你喜欢
    • 2017-01-20
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-03
    相关资源
    最近更新 更多