1

我是 C 程序员,现在我转向 Java。我正在尝试将 C 程序转换为 Java 程序。C 程序只计算词频和逆文档频率 ( tf/idf )。

我创建了一个数据类

public class Data {
    private String fileName,fileText;
    private int fileId;
    private float value;

    public void addData(String fileName, String fileText, float value){
        this.fileName = fileName;
        this.fileText = fileText;
        this.value = value;
    }

    public int getFileId(){
        return this.fileId;
    }


    public String getFileName(){
        return this.fileName;
    }

    public String getFileText(){
        return this.fileText;
    }

    public float getValue(){
        return this.value;
    }
}

该类负责存储文件名、文件文本和值(tf 值或 idf 值)。

以下类负责存储数据:

public class main {
    public static void main(String[] args) {

        HashMap<String, Data> map = new HashMap<String, Data>();
        Data dt = new Data();

        dt.addData("abc.txt", "some contents", 2);
        map.put("1",dt);
        dt.addData("w", "some more contents in second file", 3);
        map.put("2",dt);

        System.out.println(map);

    }

}

当我打印地图时,它给了我一些奇怪的值。我想,我必须声明数据类的数组?我不知道有多少文件,因此我不能放置任何静态数组编号。

另外,如何根据这个数据结构计算TF和IDF?

在 C 程序中,我只是读取文件,计算单词数除以总单词数得到 TF,一个单词除以该单词在所有文件中的总出现次数得到 IDF。我不知道如何使用上述数据结构来做到这一点。

我得到奇怪的价值观。也许这些是对象:

{2=test2.Data@19821f, 1=test2.Data@19821f}

有什么方法可以使用getFileName等函数从 Data 类中获取特定值?

4

4 回答 4

1

对于问题一,除非您 override ,否则toString()仅通过将对象直接打印到 stdout 就不太可能获得任何有意义的输出。'test2.Data@19821f' 是Object.toString()返回的 - 类名后跟对象哈希。在这种情况下,它非常有帮助地表明您的两个值都是相同的对象。

java.io.File您可以使用和来打开/读取文件java.io.FileInputStream。从字符串到整数的映射java.util.Map<String,Integer>可能有助于计算这些文件中的单词。

对于这个简单的应用程序,似乎不需要您的数据类。您已经描述了要遵循的算法,这只是用 Java 语法编写它的一个例子。

欢迎来到类型安全的美妙世界,不用担心内存泄漏。

于 2010-12-23T22:18:56.267 回答
0

您很可能希望看到数据字符串表示。

当您在任何对象(包括地图)上调用 println 时,系统调用Object.toString()

在地图的情况下,toString 方法返回地图的内容,格式类似于:

{ key = value, key2, value2 }

也就是说,打印它拥有的键值对。

现在,键和值也是对象,因此toString()调用了它们自己的方法。对于字符串,值是它自己。但是,在 的情况下Data,由于您没有提供自己的实现,因此您将获得默认值, object fully qualified name @ object.hashCode() 因此您可能会得到类似的东西:

 { 1 = Data@0xa6f2be, 2 = Data@0xa6f2be }

要更改此设置,您必须重写该toString()方法:

 class Data { 
  ... etc. etc. 
     public String toString() { 
       // return something meaningful like:
       return String.format( "Data( fileName = %s, fileText = %s, etc ", this.fileName, this.fileText );
     }
  }

至于第二个问题,基本上和 C 语言一样。也许你应该创建一个打开文件calculate()的方法,然后开始计数。可能这值得提出自己的问题。

于 2010-12-23T22:32:16.353 回答
0

您只创建了一个Data. 您可能想做更多类似的事情:

    Data dt = new Data();
    dt.addData("abc.txt", "some contents", 2);
    map.put("1",dt);

    dt = new Data();
    dt.addData("w", "some more contents in second file", 3);
    map.put("2",dt);

或者更好的是,更改Data为在其构造函数中获取属性:

    map.put("1", new Data("abc.txt", "some contents", 2));
    map.put("2", new Data("w", "some more contents in second file", 3));
于 2010-12-23T22:25:23.893 回答
0

目前尚不清楚您的问题是什么(请参阅问题下方的评论),但您的代码有一些问题。addData替换对象中数据的方法的误导性名称。但真正的问题在这里:

  dt.addData("abc.txt", "some contents", 2);
  map.put("1",dt);
  dt.addData("w", "some more contents in second file", 3);
  map.put("2",dt);

这会产生一个包含两个条目的映射,这两个条目都引用同一个 Data对象,该对象将包含上次调用addData. 更改addData为构造函数:

public Data(String fileName, String fileText, float value) {

然后将您的地图代码更改为:

map.put("1", new Data("abc.txt", "some contents", 2));
map.put("2", new Data("w", "some more contents in second file", 3));
于 2010-12-23T22:26:15.307 回答